#include <myhand.h>
int do_download(int cfd,struct sockaddr_in sin)
{
char buf[516]="";
char fileName[40]="";
printf("请输入文件名:");
scanf("%s",&fileName);
getchar();
//组装请求包
short *p1=(short*)buf;
*p1=htons(1); //表明要下载
char *p2=buf+2; //文件名段
strcpy(p2,fileName);
char *p4=p2+strlen(p2)+1; //模式段
strcpy (p4,"octet");
int size =4+strlen(p2)+strlen(p4); //要发送数据的大小
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功\n");
//循环接收回复服务器发来的消息
int fp=open("./download",O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fp<0)
{
perror("open error ");
return -1;
}
struct sockaddr_in rec;
socklen_t len =sizeof(rec);
while(1)
{
//循环接收服务器返回的数据包
bzero(buf,sizeof(buf));
ssize_t res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rec,&len);
char *p1=buf+4;
char *p2=buf+2;
unsigned short *p3=(unsigned short*)p2;
char *buf1=buf;
unsigned short*buf2=(unsigned short*)buf1;
if(3==ntohs(*buf2))
{
if(write(fp,p1,res-4)<0)
{
perror("write error");
return-1;
}
//ACK包,回复给服务器
char str[20]="";
char *str1=str;
unsigned short* str2=(unsigned short*)str1;
*str2=htons(4);
char *str3=str2+2;
unsigned short*str4=(unsigned short*)str3;
*str4=*p3;
if(sendto(cfd,str,4,0,(struct sockaddr*)&rec,sizeof(rec))<0)
{
perror("sendto error");
return -1;
}
//直到数据内容的长度小于512字节
if(res<512)
{
break;
}
else
{
printf("error");
}
}
}
return 0;
}
int do_upload(int cfd,struct sockaddr_in sin)
{
char buf[516]="";
char fileName[40]="";
printf("请输入文件名:");
scanf("%s",&fileName);
getchar();
//组装请求包
short *p1=(short*)buf;
*p1=htons(1); //表明要下载
char *p2=buf+2; //文件名段
strcpy(p2,fileName);
char *p4=p2+strlen(p2)+1; //模式段
strcpy (p4,"octet");
int size =4+strlen(p2)+strlen(p4); //要发送数据的大小
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功\n");
//循环接收回复服务器发来的消息
int fp=open("./download",O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fp<0)
{
perror("open error ");
return -1;
}
struct sockaddr_in rec;
socklen_t len =sizeof(rec);
while(1)
{
//循环接收服务器返回的数据包
bzero(buf,sizeof(buf));
ssize_t res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&rec,&len);
char *p1=buf+4;
char *p2=buf+2;
unsigned short *p3=(unsigned short*)p2;
char *buf1=buf;
unsigned short*buf2=(unsigned short*)buf1;
if(3==ntohs(*buf2))
{
if(read(fp,p1,res-4)<0)
{
perror("write error");
return-1;
}
//ACK包,回复给服务器
char str[20]="";
char *str1=str;
unsigned short* str2=(unsigned short*)str1;
*str2=htons(4);
char *str3=str2+2;
unsigned short*str4=(unsigned short*)str3;
*str4=*p3;
if(recvfrom(cfd,str,4,0,(struct sockaddr*)&rec,sizeof(rec))<0)
{
perror("sendto error");
return -1;
}
//直到数据内容的长度小于512字节
if(res<512)
{
break;
}
else
{
printf("error");
}
}
}
return 0;
}
int main(int argc, const char *argv[])
{
if(argc!=2)
{
printf("input error\n");
printf("usage:./a.out ip\n");
return -1;
}
//1、创建套接字
int cfd=socket(AF_INET,SOCK_STREAM,0);
if(cfd==-1)
{
perror("socket error");
return -1;
}
//填充服务器地址信息结构体
struct socket_in sin;
sin.sin_family =AF_INET;
sin.sin_port =htons(69);
sin.sin_addr.s_addr=inet_addr(argv[1]);
int mune=-1;
while(1)
{
ststem("clear");
printf("\t\t======1、下载=======\n");
printf("\t\t======2、下载=======\n");
printf("\t\t======0、下载=======\n");
printf("请输入功能:");
scanf("%d",&mune);
getchar();
//多分支选择
switch(mune)
{
case 1:do_download(cfd,sin);break;
//case 2:do_upload();break;
case 0:goto POS;
default:printf("请重新输入\n");
}
printf("输入任意键,按回车清空");
while(getchar()!='\n');
}
POS:
close(cfd);
return 0;
}