搭建简易客户端从tftp服务器中下载文件
生活随笔
收集整理的這篇文章主要介紹了
搭建简易客户端从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服务器中下载文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2023北京国际老年产业博览会/养老产业
- 下一篇: Windows痕迹清除技术