基于TCP的文件传输

1>fttf协议概述

简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输

特点:是应用层协议,基于UDP协议实现

数据传输模式:1、octet:二进制模式(常用)

2、mail:已经不再使用

cs 复制代码
#include<myhead.h>
#define SER_PORT 69      //服务器端口号
#define SER_IP "192.168.0.3"        //服务器ip地址

//客户端可绑定可不绑定
//#define CLI_POPR 5555              //客户端端口号
//#define CLI_IP "192.168.111.187"    //客户端ip地址

void menu()                    //菜单函数
{
	printf("******************\n");
	printf("******1.下载******\n");
	printf("******2.上传******\n");
	printf("******3.退出******\n");
	printf("******************\n");
}

//下载
int text_add()
{
	//创建套接字文件描述符
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd==-1)
	{
		perror("socket error");
		return -1;
	}

	//填充地址信息
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(SER_PORT);
	sin.sin_addr.s_addr=inet_addr(SER_IP);

	//下载数据
	char name[128]="";
	printf("请输入需要下载的文件名>>>");
	scanf("%s",name);

	//2向服务器下载请求
	char buf[516]="";
	short *p1=(short *)buf;  //操作码
	*p1=htons(1);

	char *p2=buf + 2;  //文件名  由自己输入
    strcpy(p2,name);   

	char *p4=p2+strlen(p2)+1;  //模式位   由用户输入
	strcpy(p4,"octet");
	int size=2+strlen(p2)+strlen(p4)+2;//请求包的总长度
	socklen_t addrlen=sizeof(sin);

	if(sendto(sfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("sendto 1 error");
		return -1;
	}

	int fd=-1;     //文件描述符
	int res;    //字符数
	unsigned short num=1;
	while(1)
	{
		//清空容器
		bzero(buf,sizeof(buf));
		res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		if(res==-1)
		{
			perror("recv error");
			return -1;
		}
		if(3==buf[1])
		{

			//判断块编号和本地块编号
			if(*(short *)(buf+2)==htons(num))
			{
				num++;
				fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0664);
				if(fd==-1)
				{
					perror("open error");
					return -1;
				}
			}
			//写数据
				write(fd,buf+4,res-4);
		
				//发送ack包
				buf[1]=4;
				if(sendto(sfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
				{
					perror("sendto error");
					return -1;
				}

				if(res<516)
				{
					printf("下载成功\n");
					break;
				}
				
		}
		else if(buf[1]==5)
		{
			printf("error");
			break;

		}

	}

	//关闭套接字
	close(sfd);
	close(fd);
	return 0;
}

//上传
int up_text()
{
	//创建套接字文件描述符
	int sfd=socket(AF_INET,SOCK_DGRAM,0);
	if(sfd==-1)
	{
		perror("socket error");
		return -1;
	}

	//填充地址信息
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(SER_PORT);
	sin.sin_addr.s_addr=inet_addr(SER_IP);

	//上传
	char name[128]="";
	printf("请输入需要上传的文件名>>>");
	scanf("%s",name);

	//打开文件  只读
	int rfd=-1;
	if((rfd=open(name,O_RDONLY))==-1)
	{
		perror("open error");
		return -1;
	}

	//2向服务器上传
	char buf[516]="";
	short *p1=(short *)buf;  //操作码
	*p1=htons(2);

	char *p2=buf + 2;  //文件名  由自己输入
	strcpy(p2,name);   

	char *p4=p2+strlen(p2)+1;  //模式位   由用户输入
	strcpy(p4,"octet");

	int size=2+strlen(p2)+strlen(p4)+2;//请求包的总长度
	socklen_t addrlen=sizeof(sin);

	if(sendto(sfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("sendto error");
		return -1;
	}

	int res=0;    //字符数
	unsigned short num=0;
	while(1)
	{
		//清空容器
		bzero(buf,sizeof(buf));
		res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		if(res==-1)
		{
			perror("recv error");
			return -1;
		}
		if(4==buf[1])
		{

			//判断块编号和本地块编号
			if(num==ntohs(*(short *)(buf+2)))
			{
				buf[1]=3;
				num++;
				*(short*)(buf+2)=htons(num);

				//读取数据
				res=read(rfd,buf+4,sizeof(buf)-4);
				if(res==0)
				{
					printf("上传成功\n");
					break;
				}
			}
			else
			{
				printf("上传失败\n");
				break;
			}
		}
		else if(5==buf[1])
		{
			perror("error");
			break;

		}
	}

	//关闭套接字
	close(sfd);
	close(rfd);
	return 0;
}



/************************主程序**************************/
int main(int argc, const char *argv[])
{

	int num=0;
	while(num!=3)
	{
		menu();       //调用菜单函数
		printf("请输入>>>");
		scanf("%d",&num);
		switch(num)
		{
		case 1:                    //下载

			text_add();          //调用下载函数
			break;

		case 2:                  //上传

			up_text();          //调用上传函数
			break;

		case 3:                  //退出

			break;

		default:
			printf("输入错误,请重新输入!\n");

		}

	}
	return 0;
}
相关推荐
guts°32 分钟前
10-ACL技术
网络·网络协议
群联云防护小杜42 分钟前
深度隐匿源IP:高防+群联AI云防护防绕过实战
运维·服务器·前端·网络·人工智能·网络协议·tcp/ip
2301_780789665 小时前
UDP和TCP的主要区别是什么
服务器·网络协议·web安全·网络安全·udp
_丿丨丨_6 小时前
XSS(跨站脚本攻击)
前端·网络·xss
一只栖枝7 小时前
HCIA-Security 认证精讲!网络安全理论与实战全掌握
网络·web安全·网络安全·智能路由器·hcia·it·hcia-security
FileLink跨网文件交换7 小时前
文件摆渡系统十大软件|文件摆渡系统如何构建网络安全呢?
网络
晨欣10 小时前
大型语言模型(LLM)在网络安全中最具商业价值的应用场景(Grok3 回答 DeepSearch模式)
网络·web安全·语言模型
有书Show11 小时前
个人IP的塑造方向有哪些?
网络·网络协议·tcp/ip
HHRL-yx11 小时前
C++网络编程 5.TCP套接字(socket)通信进阶-基于多线程的TCP多客户端通信
网络·c++·tcp/ip
迈威通信11 小时前
接口黑洞?破!安全堡垒?筑!冰火炼狱?战!MES7114W终极掌控
网络·安全