1.将UDP的服务器客户端重新搭建
服务器
#include <myhead.h> #define ERR_MSG(msg) do{\ fprintf(stderr,"__%d__",__LINE__);\ perror(msg);\ }while(0) #define IP "192.168.10.131" #define PORT 8888 int main(int argc, const char *argv[]) { //创建报式套接字 int sfd = socket(AF_INET,SOCK_DGRAM,0); if(sfd<0) { ERR_MSG("socket"); return -1; } printf("sfd = %d\n",sfd); struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); sin.sin_addr.s_addr = inet_addr(IP); if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0 ) { ERR_MSG("bind"); return -1; } printf("bind success\n"); struct sockaddr_in cin; socklen_t addrlen = sizeof(cin); char buf[128]=""; while(1) { bzero(buf,sizeof(buf)); if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen)<0) { ERR_MSG("recvfrom"); return -1; } printf("[%s : %d] : %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf); strcat(buf,"*_*"); if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin))<0) { ERR_MSG("sendto"); return -1; } printf("sendto success\n"); } //关闭套接字 close(sfd); return 0; }
客户端
#include <myhead.h> #define ERR_MSG(msg) do{\ fprintf(stderr,"__%d__",__LINE__);\ perror(msg);\ }while(0) #define IP "192.168.10.131" #define PORT 8888 int main(int argc, const char *argv[]) { int cfd = socket(AF_INET,SOCK_DGRAM,0); if(cfd<0) { ERR_MSG("socket"); return -1; } printf("cfd = %d\n",cfd); struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); sin.sin_addr.s_addr = inet_addr(IP); struct sockaddr_in rcvaddr; socklen_t addrlen = sizeof(rcvaddr); char buf[128]=""; while(1) { bzero(buf,sizeof(buf)); printf("请输入:"); fgets(buf,sizeof(buf),stdin); buf[strlen(buf)-1]=0; if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin))<0) { ERR_MSG("sendto"); return -1; } printf("sendto success\n"); if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rcvaddr,&addrlen)<0) { ERR_MSG("recvfrom"); return -1; } printf("[%s : %d] : %s\n",inet_ntoa(rcvaddr.sin_addr),ntohs(rcvaddr.sin_port),buf); } close(cfd); return 0; }
2. 编写tftp的下载代码
#include <myhead.h> #define ERR_MSG(msg) do{\ fprintf(stderr,"__%d__",__LINE__);\ perror(msg);\ }while(0) #define IP "192.168.10.128" #define PORT 69 int do_download(int cfd,struct sockaddr_in sin); int main(int argc, const char *argv[]) { //创建报式套接字 int cfd = socket(AF_INET,SOCK_DGRAM,0); if(cfd < 0) { ERR_MSG("socket"); return -1; } printf("cfd = %d\n",cfd); //绑定客户端的地址信息---》非必须绑定 //若不绑定则会自动绑定本机IP以及随机端口 //填充服务器的地址信息结构体,给下面的sendto函数使用 struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); sin.sin_addr.s_addr = inet_addr(IP); socklen_t addrlen = sizeof(sin); char ACK_1[4]=""; char c=0; while(1) { printf("----------------------\n"); printf("--------1.上传--------\n"); printf("--------2.下载--------\n"); printf("--------3.退出--------\n"); printf("----------------------\n"); printf("请输入>>> "); c = getchar(); while(getchar()!=10); switch(c) { case'1': break; case'2': do_download(cfd,sin); break; case'3': goto END; default: printf("输入错误,请重新输入\n"); } } END: //关闭套接字 close(cfd); return 0; } int do_download(int cfd,struct sockaddr_in sin) { char name[20]=""; printf("请输入文件名>>>"); scanf("%s",name); while(getchar()!=10); //组下载请求协议包 char buf[516]=""; unsigned short* ptr1 = (unsigned short*)buf; *ptr1 = htons(1); //操作码,下载 char* ptr2 = buf+2; strcpy(ptr2,name); char* ptr3 = ptr2 + strlen(name); *ptr3 = 0; char*ptr4 = ptr3+1; strcpy(ptr4,"octet"); int size = 2+1+1+strlen(ptr2)+strlen(ptr4); //发送下载请求给服务器 if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0) { ERR_MSG("sendto"); return -1; } printf("发送下载请求给服务器成功\n"); int fd = open("./kda.png",O_WRONLY|O_CREAT|O_TRUNC,0666); if(fd < 0) { perror("open"); return -1; } printf("文件打开成功\n"); while(1) { bzero(buf,sizeof(buf)); //接收数据包 recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen); int rec = recvfrom; if(rec < 0) { ERR_MSG("recvfrom"); return -1; } ssize_t res = read(fd,buf+4,512); ssize_t s = write(fd,buf+4,rec-4); char *p = ACK_1; short int *ack = (short int*)p; *ack = htons(4); ACK_1[2] = buf[2]; ACK_1[3] = buf[3]; //判断数据是否<512,若小鱼512,则传输结束 if(sendto(sfd,ptr3,4,0,(struct sockaddr*)&sin,sizeof(sin))<0) { ERR_MSG("sendto"); return -1; } if(rec < 516) { printf("下载完成"); break; } } close(sfd); return 0; }