基于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;
}
相关推荐
明月_清风7 分钟前
MCP vs ACP vs LSP:AI 时代三大协议的「三足鼎立」
人工智能·网络协议·agent
ACP广源盛1392462567321 分钟前
M6/M5 Pro Mac mini 端侧 AI 新形态@ACP#GSV5800 Serdes 长距离视频传输在 AI 服务中的机会与落地场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos·音视频
我爱cope1 小时前
【计算机网络 | 传输层3:TCP 协议概述:面向连接、可靠传输到底意味着什么?】
网络·网络协议·学习·tcp/ip·计算机网络·传输层
OIDCAT2 小时前
国产USB转千兆网卡芯片CH398-RTL8153国产替代实测与选型
网络·嵌入式硬件·智能硬件·国产芯片·usb转千兆网卡
M--Y4 小时前
Docker数据持久化与网络架构
网络·docker·架构
myy-learn5 小时前
30-HTTP协议
网络·网络协议·http
开开心心就好5 小时前
免费刷题软件推荐,支持导入题库自动判题
网络·网络协议·tcp/ip·jupyter·智能手机·电脑·idea
YUJIANYUE7 小时前
免费安卓手机版网络工具箱ping traceroute mtr等10+功能
网络
那年窗外下的雪.8 小时前
AIDC 学习日志|第 21 天|EVPN 多归属故障演练与中断窗口定位
网络·git·学习