8.10 网络编程——客户端从服务器中下载文件 TFTP协议
生活随笔
收集整理的這篇文章主要介紹了
8.10 网络编程——客户端从服务器中下载文件 TFTP协议
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
利用TFTP協(xié)議 客戶端從服務(wù)器中下載指定文件
過程分析
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>//打印錯(cuò)誤新的宏函數(shù) #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, "請(qǐng)輸入IP port\n");return -1;}//創(chuàng)建報(bào)式套接字int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}//綁定客戶端自身的地址信息結(jié)構(gòu)體 ---> 非必須綁定 //填充服務(wù)器的IP地址以及端口號(hào) -->因?yàn)榭蛻舳艘鲃?dòng)發(fā)送數(shù)據(jù)包給服務(wù)器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; //存儲(chǔ)接收到的數(shù)據(jù)包來自哪里socklen_t addrlen = sizeof(rcv_addrmsg);//發(fā)送請(qǐng)求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("請(qǐng)輸入要下載的文件名>>>");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;//將數(shù)據(jù)包發(fā)送給服務(wù)器,所以地址信息結(jié)構(gòu)體需要填服務(wù)器的信息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; //定義塊編號(hào)while(1){//接收數(shù)據(jù)包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++; //塊編號(hào)++char *ptr = buf; //數(shù)據(jù)包short int* rpa = (short int*)ptr; //數(shù)據(jù)包操作碼首地址short int* rpb = rpa+1; //數(shù)據(jù)包塊編號(hào)首地址char *rpc = ptr+4; //數(shù)據(jù)包數(shù)據(jù)首地址char *errptr = buf; //錯(cuò)誤包short int* epa = (short int*)errptr; //錯(cuò)誤包操作碼地址short int* epb = epa+1; //錯(cuò)誤包的差錯(cuò)碼地址char* epc = (char*)(epb+1); //錯(cuò)誤包差錯(cuò)信息首地址char ACK[5] = ""; //ACKbzero(ACK,sizeof(ACK));short int *acka = (short int*)ACK; //ACK操作碼首地址*acka = htons(4);short int* ackb = acka+1; //ACK塊編號(hào)首地址*ackb = htons(i);//判斷是否是數(shù)據(jù)包if(3==ntohs(*rpa)&&i==ntohs(*rpb)){//判斷數(shù)據(jù)包中數(shù)據(jù)大小是否小于512字節(jié)if((res-4)<512){//寫入文件write(fd,rpc,res-4);//發(fā)送ACK驗(yàn)證if(sendto(sfd,ACK,4,0,(struct sockaddr*)&rcv_addrmsg,addrlen)<0){ERR_MSG("sendto");return -1;}//printf("sendto success 結(jié)束\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); //打印錯(cuò)誤信息}printf("下載成功!\n");//關(guān)閉套接字close(sfd);return 0; }測(cè)試結(jié)果
總結(jié)
以上是生活随笔為你收集整理的8.10 网络编程——客户端从服务器中下载文件 TFTP协议的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (2022杭电多校三)1002-Boss
- 下一篇: html项目符号怎么设成大圆点,Word