Linux下基于TCP的简易文件传输(socket编程) 您所在的位置:网站首页 通过Socket实现文件上传上传文件 Linux下基于TCP的简易文件传输(socket编程)

Linux下基于TCP的简易文件传输(socket编程)

2023-10-13 18:00| 来源: 网络整理| 查看: 265

Linux下基于TCP的简易文件传输(socket编程) OSI和TCP/IP:关于TCP/IP协议关于TCP协议TCP编程的一般步骤[^2] TCP文件传输实现功能概述服务器编程客户端编程运行结果 总结遇到的问题服务器编程

OSI和TCP/IP:

OSI 模型本身不是网络体系结构的全部内容,它并未确切地描述用于各层的协议和服务,仅提出每一层应该做什么。不过OSI 已经为各层制定了标准,但并不是参考模型的一部分,而作为单独的国际标准公布的。 TCP/IP 是一组用于实现网络互连的通信协议。Internet 网络体系结构以TCP/IP 为核心。基于TCP/IP 的参考模型将协议分成四个层次,它们分别是:网络访问层、网际互联层、传输层(主机到主机)、和应用层。 OSI模型和TCP/IP模型的对应关系

关于TCP/IP协议

TCP/IP是一个网络通信模型,以及一整个网络传输协议家族,是网际网络的基础通信架构。因为该协议家族的两个核心协议:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准。故此它常被通称为TCP/IP协议族(TCP/IP Protocol Suite),简称TCP/IP。

一. TCP/IP模型 :TCP/IP 是一组用于实现网络互连的通信协议。Internet 网络体系结构以 TCP/IP 为核心。基于TCP/IP 的参考模型将协议分成四个层次,它们分别是:网络访问层、网际互联层、传输层(主机到主机)、和应用层。

应用层 应用层对应于 OSI 参考模型的高层,为用户提供所需要的各种服务,例如:FTP、Telnet、DNS、SMTP 等。传输层 传输层对应于 OSI 参考模型的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。该层定义了两个主要的协议:传输控制协议(TCP)和用户数据协议(UDP)。TCP 协议提供的是一种可靠的、通过“三次握手”来连接的数据传输服务;而 UDP 协议提供的则是不保证可靠的(并不是不可靠)、无连接的数据传输服务.网际互联层网际互联层对应于 OSI 参考模型的网络层,主要解决主机到主机的通信问题。它所包含的协议设计数据包在整个网络上的逻辑传输。注重重新赋予主机一个 IP 地址来完成对主机的寻址,它还负责数据包在多种网络中的路由。该层有三个主要协议:网际协议(IP)、互联网组管理协议(IGMP)和互联网控制报文协议(ICMP)。IP 协议是网际互联层最重要的协议,它提供的是一个可靠、无连接的数据报传递服务。网络接口层(即主机-网络层) 网络接入层与 OSI 参考模型中的物理层和数据链路层相对应。它负责监视数据在主机和网络之间的交换。事实上,TCP/IP 本身并未定义该层的协议,而由参与互连的各网络使用自己的物理层和数据链路层协议,然后与 TCP/IP 的网络接入层进行连接。地址解析协议(ARP)工作在此层,即 OSI 参考模型的数据链路层;

二. IP协议 :IP(Internet Protocol)协议是 TCP/IP 的核心协议。IP 协议(Internet Protocol)又称互联网协议,是支持网间互连的数据报协议。它提供网间连接的完善功能, 包括 IP 数据报规定互连网络范围内的 IP 地址格式。 目前的 IP 地址(IPv4:IP 第 4 版本)由 32 个二进制位表示,每 8 位二进制数为一个整数,中间由小数点间隔,如 159.226.41.98,整个 IP 地址空间有 4 组 8 位二进制数,由表示主机所在的网络的地址以及主机在该网络中的标识共同组成,它通常被分为A,B,C,D,E五类,其中商业应用只用到A,B,C三类1。 在这里插入图片描述

关于TCP协议

(1)TCP(传输控制协议) TCP 是一种可靠的面向连接的传送服务。主机交换数据必须首先建立连接,传输完毕后断开连 接。它用位流通信,即数据被作为无结构的字节流。它提供反馈重发机制,从而保证数据的可靠传 输。 (2)三次握手 TCP 连接建立是一个三次握手过程,三次握手的目的是使数据的发送和接收同步。TCP 连接过程 如下图所示: TCP 连接过程如下:

服务器必须准备好接受外来的连接。通过调用 socket, bind, listen 函数完成。称为被动打开。客户通过调用 connect 进行主动打开。这引起客户 TCP 发送一个 SYN 分节,告诉服务器客户将在 连接中发送的数据的初始序列号。服务器必须确认客户的 SYN,同时自己也得发送一个 SYN 分节。服务器以单个分节向客户发送 SYN 和对客户的 SYN 的 ACK。客户必须确认服务器的 SYN。

在这里插入图片描述

TCP编程的一般步骤2

TCP编程的服务器端一般步骤是:   1、创建一个socket,用函数socket();   2、设置socket属性,用函数setsockopt(); * 可选   3、绑定IP地址、端口等信息到socket上,用函数bind();   4、开启监听,用函数listen();   5、接收客户端上来的连接,用函数accept();   6、收发数据,用函数send()和recv(),或者read()和write();   7、关闭网络连接;   8、关闭监听;

TCP编程的客户端一般步骤是:   1、创建一个socket,用函数socket();   2、设置socket属性,用函数setsockopt();* 可选   3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选   4、设置要连接的对方的IP地址和端口等属性;   5、连接服务器,用函数connect();   6、收发数据,用函数send()和recv(),或者read()和write();   7、关闭网络连接;

TCP文件传输实现 功能概述

利用socket编程基础实现一个基础的文件传输程序,可以在不同设备之间传输文件,视频,图片,音乐等内容。

服务器编程 #include #include #include #include #include #include #include #include #include #include #include #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define SERVER_PORT 8000 //监听本机8000端口 #define MAX 4096 #define BUF_SIZE 10240 void empty_stdin() { int c; do { c = getchar(); } while (c != '\n' && c != EOF); } int main(void) { struct sockaddr_in serveraddr,clientaddr; int sockfd,addrlen,confd,len; char ipstr[128]; char buf[16]; pid_t pid; //1.socket sockfd = socket(AF_INET,SOCK_STREAM,0); //2.bind bzero(&serveraddr,sizeof(serveraddr)); //地址族协议ipv4 serveraddr.sin_family = AF_INET; //ip地址 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(SERVER_PORT); bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)); //3.listen listen(sockfd,20);//128作为可同时链接的数量上线 //4. accept阻塞监听客户端的链接请求 addrlen = sizeof(clientaddr); confd = accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen); //如果有客户端连接上服务器,就输出客户端的ip地址和端口号 printf("client ip %s\tport %d\n", inet_ntop(AF_INET,(struct sockaddr *)&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr)),ntohs(clientaddr.sin_port)); int flag=1; while(flag){ char fdownload[100] = {0}; recv(confd,fdownload,100,0);//接收客户端的下载请求获得文件名 if(!strcmp(fdownload,"quit")) break;//客户端输入quit退出程序 else{ FILE *fp = fopen(fdownload, "rb"); //以二进制方式打开文件 if(fp == NULL){ printf("Cannot open file, press any key to exit!\n"); break; } struct stat statbuf; //这三行代码获得文件的大小,得到文件字节数 stat(fdownload,&statbuf); int size=statbuf.st_size; char t[20]; printf("%d \n",size);//文件大小 sprintf(t,"%d",size);//转换整数到字符型数据 //printf("start transfer\n"); send(confd,t,20,0);//把文件大小发给客户端 char buffer[BUF_SIZE] = {0}; //缓冲区 long nCount,mc=0; long si,sj,m,c; recv(confd,t,4,0);//获得开始传输指令 if(t[0]=='o'){ printf("start transfer\n"); /*一下内容开始发送文件内容 ,因为文件大小会超出发送缓冲区大小,因此在这里循环调用send()函数进行发送,每一次发送nCount个字节,传输缓冲区这里设置为10240(并不合理,但不想花脑子想这个问题)*/ while( (nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 ){ mc=mc+nCount; si=mc*30/size;//这里开始计算传输比例,式字计算顺序不能更改,否则出现数据溢出,而产生错误。 m=si-sj; printf("%*s|%d%%",30-si,"",(mc*100/size));//在固定位置打印百分数 printf("\r\033["); //退格 for(int t=0;t struct sockaddr_in serveraddr; int confd,len; char ipstr[] = "192.168.1.100";//这是服务器的地址,使用ifconfig来查看 char buf[MAXLINE]; //1.创建一个socket confd = socket(AF_INET,SOCK_STREAM,0); //2.初始化服务器地址,指明我要连接哪个服务器 bzero(&serveraddr,sizeof(serveraddr)); serveraddr.sin_family = AF_INET; inet_pton(AF_INET,ipstr,&serveraddr.sin_addr.s_addr); serveraddr.sin_port = htons(SERVER_PORT); //3.链接服务器 connect(confd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)); int flag=1,size; char t[20]; memset(&t,0,sizeof(t)); while(flag){ char fdownload[100] = {0}; printf("Input filename to download: "); gets(fdownload); if(!strcmp(fdownload,"quit")) break; send(confd,fdownload,100,0); char filename[100] = {0}; //文件名 len=recv(confd,t,20,0); size=atoi(t); double sizel; sizel=size/1048576.0; printf("filesize; %.2f MB\n ",sizel); printf("Input filename to save: "); gets(filename); if(!strcmp(filename,"quit")) break; else{ FILE *fp = fopen(filename, "wb"); //以二进制方式打开(创建)文件 if(fp == NULL){ printf("Cannot open file, press any key to exit!\n"); break; } send(confd,"o",4,0); char buffer[BUF_SIZE] = {0}; //文件缓冲区 long nCount,mc=0; long si,sj,m,c; printf("Start receive!\n"); while( (nCount = recv(confd, buffer, BUF_SIZE, 0)) > 0 ){ mc=mc+nCount; si=mc*30/size; m=si-sj; printf("%*s|%d%%",30-si,"",(mc*100/size)); printf("\r\033["); //退格 for(int t=0;t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有