日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

8.10 网络编程——客户端从服务器中下载文件 TFTP协议

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 8.10 网络编程——客户端从服务器中下载文件 TFTP协议 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

利用TFTP協議 客戶端從服務器中下載指定文件

過程分析

TFTP通信過程

  • 服務器在69號端口等待客戶端的請求
  • 服務器若批準此請求,則使用 臨時端口 與客戶端進行通信。
  • 每個數據包的編號都有變化(從1開始)
  • 每個數據包都要得到ACK的確認,如果出現超時,則需要重新發送最后的數據包或ACK包
  • 數據長度以512Byte傳輸的,小于512Byte的數據意味著數據傳輸結束。
  • 代碼示例

    #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协议的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。