8.10 网络编程——客户端从服务器中下载文件 TFTP协议
生活随笔
收集整理的這篇文章主要介紹了
8.10 网络编程——客户端从服务器中下载文件 TFTP协议
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
利用TFTP協議 客戶端從服務器中下載指定文件
過程分析
TFTP通信過程
代碼示例
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h>//打印錯誤新的宏函數 #define ERR_MSG(msg) do{\fprintf(stderr, " __%d__ ", __LINE__);\perror(msg);\ }while(0)int main(int argc, const char *argv[]) {if(argc < 2){fprintf(stderr, "請輸入IP port\n");return -1;}//創建報式套接字int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}//綁定客戶端自身的地址信息結構體 ---> 非必須綁定 //填充服務器的IP地址以及端口號 -->因為客戶端要主動發送數據包給服務器struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(69);sin.sin_addr.s_addr = inet_addr(argv[1]);struct sockaddr_in rcv_addrmsg; //存儲接收到的數據包來自哪里socklen_t addrlen = sizeof(rcv_addrmsg);//發送請求char buf[517] = "";bzero(buf, sizeof(buf));char* ptr = buf;short int* pa = (short int*)ptr;*pa = htons(1);char *pb = ptr+2;char filename[128] = "";printf("請輸入要下載的文件名>>>");scanf("%s",filename);getchar();strcpy(pb,filename);char* pd = pb+strlen(filename)+1;strcpy(pd,"octet");int size = 2+strlen(pb)+1+strlen(pd)+1;//將數據包發送給服務器,所以地址信息結構體需要填服務器的信息if(sendto(sfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}//printf("sendto success\n");//打開文件獲取文件描述符int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fd<0){ERR_MSG("open");return -1;}short int i=0; //定義塊編號while(1){//接收數據包bzero(buf,sizeof(buf));ssize_t res;if((res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&rcv_addrmsg,&addrlen)) < 0){ERR_MSG("recvfrom");return -1;}i++; //塊編號++char *ptr = buf; //數據包short int* rpa = (short int*)ptr; //數據包操作碼首地址short int* rpb = rpa+1; //數據包塊編號首地址char *rpc = ptr+4; //數據包數據首地址char *errptr = buf; //錯誤包short int* epa = (short int*)errptr; //錯誤包操作碼地址short int* epb = epa+1; //錯誤包的差錯碼地址char* epc = (char*)(epb+1); //錯誤包差錯信息首地址char ACK[5] = ""; //ACKbzero(ACK,sizeof(ACK));short int *acka = (short int*)ACK; //ACK操作碼首地址*acka = htons(4);short int* ackb = acka+1; //ACK塊編號首地址*ackb = htons(i);//判斷是否是數據包if(3==ntohs(*rpa)&&i==ntohs(*rpb)){//判斷數據包中數據大小是否小于512字節if((res-4)<512){//寫入文件write(fd,rpc,res-4);//發送ACK驗證if(sendto(sfd,ACK,4,0,(struct sockaddr*)&rcv_addrmsg,addrlen)<0){ERR_MSG("sendto");return -1;}//printf("sendto success 結束\n");break;}else{write(fd,rpc,512);if(sendto(sfd,ACK,4,0,(struct sockaddr*)&rcv_addrmsg,addrlen)<0){ERR_MSG("sendto");return -1;}//printf("sendto success 512 \n");}}elseprintf("ERROR:%s\n",epc); //打印錯誤信息}printf("下載成功!\n");//關閉套接字close(sfd);return 0; }測試結果
總結
以上是生活随笔為你收集整理的8.10 网络编程——客户端从服务器中下载文件 TFTP协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (2022杭电多校三)1002-Boss
- 下一篇: html项目符号怎么设成大圆点,Word