4/11日作业
1、基于UDP的TFTP文件传输
1 #include<stdio.h>2 #include<sys/types.h>3 #include<sys/socket.h>4 #include<netinet/in.h>5 #include<netinet/ip.h>6 #include<string.h>7 #include<arpa/inet.h>8 #include<unistd.h>9 #include<sys/stat.h>10 #include<fcntl.h>11 #define ERR_MSG(msg) do{\\12 fprintf(stderr,"%d",__LINE__);\\13 perror("msg");\\14 }while(0)15 16 #define SER_IP "192.168.2.131"17 #define SER_PORT 6918 19 #define CLI_IP "192.168.0.111"20 #define CLI_PORT 777721 22 23 void Download();24 25 void Upload()26 {27 while(1)28 sleep(1);29 }30 31 32 33 int main(int argc, const char *argv[])34 {35 int option =-1;36 while(1)37 {38 printf("************************\\n");39 printf("********1、下载*********\\n");40 printf("********2、上传*********\\n");41 printf("********3、退出*********\\n");42 printf("************************\\n");43 scanf("%d",&option);44 while(getchar() != 10);45 if(1 == option)46 Download();47 else if(2 == option)48 Upload();49 else if(3 == option)50 break;51 }52 53 54 55 /*56 ssize_t res = 0;57 58 while(1)59 {60 bzero(buf,sizeof(buf));61 printf("请输入>>>");62 fgets(buf,sizeof(buf),stdin);63 buf[strlen(buf)-1] = 0;64 65 66 //发送数据67 if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0)68 {69 ERR_MSG("sendto");70 return -1;71 }72 printf("发送成功\\n");73 74 //接收数据75 error_message(*(short*)(buf+2));76 bzero(buf,sizeof(buf));77 //继续接受数据包发送方的地址信息,给sendto使用78 res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rcvaddr,&addrlen);79 if(res < 0) 80 {81 ERR_MSG("recvfrom");82 return -1;83 }84 printf("[%s:%d]: %s\\n",inet_ntoa(rcvaddr.sin_addr),ntohs(rcvaddr.sin_port),buf);85 86 }87 */88 89 //关闭90 return 0;91 }92 93 94 void Download()95 {96 //创建报式套接字97 int cfd = socket(AF_INET,SOCK_DGRAM,0);98 if(cfd < 0)99 {
100 ERR_MSG("socket");
101 return;
102 }
103
104 char buf[516]={0};
105
106 //创建填充服务器地址信息结构体
107 struct sockaddr_in sin;
108 sin.sin_family = AF_INET;
109 sin.sin_port = htons(SER_PORT);
110 sin.sin_addr.s_addr = inet_addr(SER_IP);
111
112 socklen_t addrlen = sizeof(sin);
113
114 //设置读请求
115 *(short*)buf = htons(1);
116 //printf("%hd\\t__%d__\\n",ntohs(*(short*)buf),__LINE__);
117
118 //将文件名写入到buf中
119 printf("请输入要下载的文件名>>>>>>\\n");
120 scanf("%s",buf+2);
121 while(getchar() != 10);
122 char pathname[128]="";
123 strcpy(pathname,buf+2);
124
125 strcpy(buf+2+strlen(buf+2)+1,"octet");
126
127 printf("%hd %s %s\\n",ntohs(*(short*)buf),buf+2,buf+2+strlen(buf+2)+1);
128
129
130
131
132 char *p1 = buf+2+strlen(buf+2)+1;
133 int size = 4 + strlen(buf+2)+strlen(p1)+1;
134 //发送数据
135 if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) < 0)
136 {
137 ERR_MSG("sendto");
138 return;
139 }
140 printf("发送成功 size=%d\\n",size);
141
142 ssize_t res = 0;
143 short count=1;
144
145 int fd = -1;;
146 while(1)
147 {
148 //接收数据
149 bzero(buf,sizeof(buf));
150 res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
151 if(res < 0)
152 {
153 ERR_MSG("recvfrom");
154 return;
155 }
156 // printf("[%s:%d]: %s\\n",inet_ntoa(rcvaddr.sin_addr),ntohs(rcvaddr.sin_port),buf);
157 // printf("%d : %d\\t%s\\n",ntohs(*(short*)buf),ntohs(*(short*)(buf+2)),buf+4);
158 if(ntohs(*(short*)buf) == 3)
159 {
160 if(1 == ntohs(*(short*)(buf+2)))
161 {
162 //创建文件
163 fd = open(pathname,O_WRONLY|O_CREAT|O_TRUNC,0664);
164 if(fd < 0)
165 {
166 ERR_MSG("open");
167 return;
168 }
169 }
170
171 if(ntohs(*(short*)(buf+2)) == count)
172 {
173 write(fd,buf+4,res-4);
174 if(res < 0)
175 {
176 ERR_MSG("read");
177 break;
178 }
179 else if(res < 512)
180 {
181 printf("Download sucess\\n");
182 break;
183 }
184 //发送数据
185 bzero(buf,sizeof(buf));
186 *(short *)buf = htons(4);
187 *((short *)(buf+2))=htons(count++);
188
189 if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin)) < 0)
190 {
191 ERR_MSG("sendto");
192 return ;
193 }
194 }
195 }
196 else if(ntohs(*(short *)buf) == 5)
197 {
198 printf("%s __%d__\\n",buf+4,__LINE__);
199 break;
200 }
201 // printf("发送成功\\n");
202
203 }
204
ubuntu@ubuntu:TFTP$ gcc 02_udpCli_TFTP.c
ubuntu@ubuntu:TFTP$ ./a.out
************************
********1、下载*********
********2、上传*********
********3、退出*********
************************
1
请输入要下载的文件名>>>>>>
5.png
1 5.png octet
发送成功 size=15
Download sucess
************************
********1、下载*********
********2、上传*********
********3、退出*********
************************
^C
ubuntu@ubuntu:TFTP$ ls
02_udpCli_TFTP.c 2 5 a.out asd.c d huahua.c
1.png 2octet 5.png asd asdoctet dict.txt
ubuntu@ubuntu:TFTP$ eog 5.png
ubuntu@ubuntu:TFTP$