#include<myhead.h>
int task_download(int client_fd,struct sockaddr_in serve_info)
{
//定义变量存储下载请求包
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(client_fd,buf,size,0,(struct sockaddr*)&serve_info,sizeof(serve_info))==-1)
{
perror("sendto error");
return -1;
}
printf("已经向服务器发送下载请求\n");
//首先判断文件在当前文件夹下是否存在
if(access(filename,F_OK)==0) //-1不存在 0存在
{
//存在
printf("目录下已经存在该文件名的文件了,将重新写入\n");
}
int downfd=-1;
if((downfd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("open error");
return -1;
}
//与服务器发送来的包进行解析分析与应答
while(1)
{
bzero(buf, sizeof(buf));
int res = -1;
if((res = recvfrom(client_fd, buf, sizeof(buf), 0,NULL,NULL)) == -1){
perror("recvfrom error");
return -1;
}
short *p1 = (short *)buf;
if(*p1 == htons(3))
{
write(downfd, buf+4, res-4);
*p1 = htons(4);
sendto(client_fd, buf, 4, 0, (struct sockaddr *)&serve_info, sizeof(serve_info));
if(res < 516)
{
break;
}
}
else
{
printf("未知错误,错误码: %d\n", buf[3]);
close(downfd);
return -1;
}
}
return 0;
}
int main(int argc, const char *argv[])
{
if(argc!=2)
{
printf("input error\n note->./a.out ip\n");
return -1;
}
int client_fd=-1;
if((client_fd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
perror("socket error");
return -1;
}
//recvfrom/sendto
struct sockaddr_in serve_info;
serve_info.sin_family=AF_INET;
serve_info.sin_port=htons(69);//UDP对应的tftp端口号
serve_info.sin_addr.s_addr=inet_addr(argv[1]);
int mune=-1;
while(1)
{
system("clear");
printf("\t\t=======================1->下载=======================\n");
printf("\t\t=======================2->上传=======================\n");
printf("\t\t=======================3->退出=======================\n");
printf("请选择功能->");
scanf("%d",&mune);
getchar();
switch(mune)
{
case 1:
task_download(client_fd,serve_info);
break;
case 2:
//task_upload();
break;
case 3:
goto quit;
default:
printf("input error\n");
break;
}
while(getchar()!='\n');
}
quit:
close(client_fd);
return 0;
}