代码:
#include <myhead.h>
//实现下载功能
int download(int cfd,struct sockaddr_in sin)
{
char buf[516] = ""; //定义资源包
char fileName[128] = ""; //定义文件名
printf("请输入文件名:");
scanf("%s",fileName);
getchar();
//打开文件
int fd = -1;
if((fd = open(fileName,O_RDWR|O_CREAT|O_TRUNC|0666)) == -1)
{
perror("open error"); //读写形式创建文件,文件名为输入的文件名
return -1;
}
//组装请求包
short *p1 = (short *)buf;
*p1 = htons(1);
char *p2 = buf + 2;
strcpy(p2,fileName);
char *p3 = p2+strlen(p2)+1;
strcpy(p3,"octet");
int size = 4+strlen(p2)+strlen(p3); //整体长度
//先发送下载请求到服务器
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功!n");
socklen_t socklen = sizeof(sin);
char *p5 = buf + 4; //确定数据的位置以及差错信息的位置
while(1)
{
bzero(buf,sizeof(buf));
int res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
int A = buf[1]; //因为小端存储,操作码放在buf的第二位
if(A == 3) //当操作码为3时,证明是数据包,正常接收
{
write(fd,p5,sizeof(buf));
buf[1]=4; //将操作码改为4,即ACK
//将buf前四位发送回去,因为操作码已经修改,发回去四位当做ACK回复
sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin));
}
else if(A == 5) //当操作码为5时,证明为ERROR
{
printf("%sn",p5);
return -1;
}
if(res < 516) //当接收到的字节数小于516时,证明已经接收完成,关闭循环
break;
}
printf("下载完成n");
close(fd); //关闭文件
}
//实现上传功能
int upload(int cfd,struct sockaddr_in sin)
{
char buf[516] = ""; //定义资源包
char fileName[128] = ""; //定义文件名
printf("请输入文件名:");
scanf("%s",fileName);
getchar();
//打开文件
int fd = -1;
if((fd = open(fileName,O_RDONLY)) == -1)
{
perror("open error"); //只读形式打开文件,文件名为输入的文件名
return -1;
}
//组装请求包
short *p1 = (short *)buf;
*p1 = htons(2); //操作码为2代表要上传
char *p2 = buf + 2;
strcpy(p2,fileName);
char *p3 = p2+strlen(p2)+1;
strcpy(p3,"octet");
int size = 4+strlen(p2)+strlen(p3); //整体长度
//先发送上传请求到服务器
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("sendto error");
return -1;
}
printf("请求成功!n");
socklen_t socklen = sizeof(sin);
int n = 1;
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&socklen);
int res = read(fd,buf+4,sizeof(buf)-4); //将文件的512位写入数据包
buf[1]=3; //将操作码改为3,即数据包
//将buf发送,因为操作码已经修改,发回去数据加上了操作码和块编号
sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));
if(res==0) //证明已经上传完成,关闭循环
break;
}
printf("上传完成n");
close(fd); //关闭文件
}
int main(int argc, const char *argv[])
{
if(argc != 2)
{
printf("input error");
return -1;
}
//创建套接字
int cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
//填充服务器结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(69);
sin.sin_addr.s_addr = inet_addr(argv[1]);
int key = 0;
while(1)
{
system("clear");
printf("tt菜单ttn");
printf("tt1.下载ttn");
printf("tt2.上传ttn");
printf("tt0.关闭ttn");
printf("请输入选项:");
scanf("%d",&key);
getchar();
switch(key)
{
case 1:
{
//下载
int A =download(cfd,sin);
};break;
case 2:
{
//上传
int B =upload(cfd,sin);
};break;
case 0:
{
goto A;
};break;
default:
printf("请输入正确的选项!n");
}
//阻塞
printf("输入任意键,按回车清空");
while(getchar() != 'n');
}
A:
close(cfd);
return 0;
}
原文地址:https://blog.csdn.net/qq_57071955/article/details/134541233
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_7245.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。