> 文章列表 > 4/11日作业

4/11日作业

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$