- #include
- #define SER_PORT 69
- int main(int argc, const char *argv[])
- {
- int cfd=socket(AF_INET,SOCK_DGRAM,0);//创建套接字文件用于发送给服务器
- if(cfd==-1)//判断套接字文件是否创建成功
- {
- perror("socket error");
- return -1;
- }
- printf("*********************\n");
- printf("********1.下载*******\n");
- printf("********2.上传*******\n");
- printf("********3.退出*******\n");
- printf("*********************\n");
-
- struct sockaddr_in sin;//定义地址信息结构体 用于发给服务器
- sin.sin_family=AF_INET;//IPV4协议
- sin.sin_port=htons(SER_PORT);//端口号 默认为69
- sin.sin_addr.s_addr=inet_addr(argv[1]);//外部传参写入IP地址
- socklen_t socklen=sizeof(sin);//求结构体大小 sizeof(sin)不能取地址
- char buf[516]="";//定义读写请求的包
- char ack[4]="";//定义ACK应答包
- short *a1=(short *)ack;//定义一个指针a1指向字符串ack首地址 ack为char类型 但指针是short要强转
- *a1=htons(4);//给字符数组ack前两个字节赋值为4 因为要上传到服务器 所以要转成网络字节序
- short *a2=(short*)ack+1;//定义一个指针a2指向ack后两字节 short类型指针偏移量为2字节
- int a=0;
- int b=1;
- char filename[20]="";//定义下载文件名的字符数组
- char filename1[20]="";//定义上传文件名的字符数组
- while(1)//循环
- {
- *a2=htons(b);//
- bzero(buf,sizeof(buf));
- short*p1=(short*)buf;
- scanf("%d",&a);//输入数字 1.下载 2.上传 3.退出
- if(3==a)
- break;
- if(1==a)
- {
- *p1=htons(a);
- getchar();
- char *p2=buf+2;
- printf("请输入要下载的文件名\n");
- scanf("%s",filename);//获取文件名
- strcpy(p2,filename);
- getchar();
- char*p3=p2+strlen(p2);
- *p3=0;
- char *p4=p3+1;
- strcpy(p4,"octet");
- sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));
- int fp=open(filename,O_RDWR|O_CREAT|O_TRUNC,0664);
- if(fp==-1)
- {
- perror("open error");
- return -1;
- }
- while(1)
- {
- bzero(buf,sizeof(buf));
- size_t res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
- int ret=write(fp,buf+4,res-4);
- if(ret<512)
- break;
- sendto(cfd,ack,sizeof(ack),0,(struct sockaddr*)&sin,sizeof(sin));
- b++;
- *a2=htons(b);
- }
- close(fp);
- }else if(2==a)
- {
- printf("请输入要上传的文件名");
- scanf("%s",filename1);
- printf("文件名为:%s",filename1);
- }
-
- }
- close(cfd);
- return 0;
- }
-