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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

搭建简易客户端从tftp服务器中下载文件

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

tftp協議概述

? ? ? ? tftp(簡單文件傳輸協議)是基于UDP適用于網絡上進行文件傳輸的標準協議。

特點:

? ? ? ? 應用層協議,基于UDP協議實現。

下載文件功能實現過程 1.服務器在69號端口等待客戶端的請求。 2.客戶端發送讀寫請求報文,服務器批準并使用臨時接口與客戶端進行通信。 3.服務器向客戶端發送數據包并在數據包頭設置塊編碼(可在客戶端校驗次序)。 4.客戶端收到數據包后向服務器發送帶有操作碼和塊編碼的ACK 5.客戶端校驗收到的數據是否小于512byte,若小于則停止繼續接收信息。

請求代碼編寫:

????????客戶端的請求代碼由2byte的操作碼+未知大小的文件名+0(1byte)+數據傳輸模式+0(1byte)組成本次通過字符串完成請求代碼的編寫

//創建讀請求包unsigned char buf[516]="";char *ptr = buf;short int * pa =(short int *)ptr;*pa = htons(1);//1為讀2為寫,并轉化成網絡字節序char *pb=ptr+2;strcpy(pb,filename);char * pc= pb+strlen(pb);char *pd=pc+1;strcpy(pd,"octet");

收發功能編寫

由ACK與數據包的前4byte可見兩者的3~4byte都存放塊編碼,獲取ACK只需將從服務器接受到的數據包取前4byte再將操作碼改為4即可。

?

while (1){bzero(buf,sizeof(buf));//接收數據包res = recvfrom(sfd,buf,516,0,(struct sockaddr*)&sin,&addrlen);printf(" %ld ",n);n+=res;if (res<0){ERR_MSG("recvfrom");return -1;}write(fb,buf+4,res-4);buf[1]=4; //將操作碼改為4,pg的前四個字節就是ACKif(sendto(sfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))<0)//發送ACK包{ERR_MSG("sendto");return -1;}if (res<516){break;}}

總代碼

#include <sys/types.h> #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #define ERR_MSG(msg) do {\fprintf(stderr,"_%d_",__LINE__);\perror(msg);\ }while(0)#define N 512 #define filename "5.png"int main(int argc, const char *argv[]) {if (argc<3){printf("請輸入端口號和IP\n");return -1;}int port = atoi(argv[2]);//創建報式套接字int sfd =socket(AF_INET,SOCK_DGRAM,0);if (sfd<0){ERR_MSG("socket");return -1;}printf("create socket success\n");//填充地址信息結構體,真實的地址信息結構體與協議族有關//AF_INEt 詳見 man 7 ipstruct sockaddr_in sin;sin.sin_family =AF_INET;sin.sin_port =htons(port);//主機字節序轉網絡字節序的端口號sin.sin_addr.s_addr = inet_addr(argv[1]);//創建讀請求包unsigned char buf[516]="";char *ptr = buf;short int * pa =(short int *)ptr;*pa = htons(1);//1為讀2為寫,并轉化成網絡字節序char *pb=ptr+2;strcpy(pb,filename);char * pc= pb+strlen(pb);char *pd=pc+1;strcpy(pd,"octet");size_t sz = 2+strlen(pb)+1+strlen("octet")+1; //數據包大小//發送下載請求if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("sendto");return -1;}int fb= open("./5.png",O_WRONLY|O_CREAT,0664);//創建一個文件將讀取到的數據寫入該文件socklen_t addrlen= sizeof(sin);ssize_t res=0;long int n=0;while (1){bzero(buf,sizeof(buf));//接收數據包res = recvfrom(sfd,buf,516,0,(struct sockaddr*)&sin,&addrlen);printf(" %ld ",n);n+=res;if (res<0){ERR_MSG("recvfrom");return -1;}write(fb,buf+4,res-4);buf[1]=4; //將操作碼改為4,pg的前四個字節就是ACKif(sendto(sfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))<0)//發送ACK包{ERR_MSG("sendto");return -1;}if (res<516){break;}}close(sfd);close(fb);return 0; }

測試結果

? ? ? ? 編譯運行后通過eog圖片可見圖片下載成功。

在服務器中也顯示傳輸完成

?

?

總結

以上是生活随笔為你收集整理的搭建简易客户端从tftp服务器中下载文件的全部內容,希望文章能夠幫你解決所遇到的問題。

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