欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 基于TCP的文件传输

基于TCP的文件传输

2024/10/24 17:22:38 来源:https://blog.csdn.net/2301_76740986/article/details/141173242  浏览:    关键词:基于TCP的文件传输

1>fttf协议概述

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

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

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

                         2、mail:已经不再使用

#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;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com