代码

#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*)&amp;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*)&amp;sin,&amp;socklen);
		int res = read(fd,buf+4,sizeof(buf)-4); //将文件的512位写入数据包
		buf[1]=3;   //将操作码改为3,即数据包
		
		//将buf发送,因为操作码已经修改,发回去数据加上了操作码和块编号
		sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&amp;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",&amp;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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注