基于TCP协议的文件传输系统

TCP文件传输(服务端的文件下载) TCP协议传输文件的服务端接收。 阅读详情

最简单的一对一的服务端网络端通信(socket)
Socket=(IP地址:端口号),例如:如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)
socket可以理解成计算机提供给程序员的接口,数据在客户端和服务端之间的socket之间传输。socket把复杂的TCP/IP协议封装,对于程序员来说只要利用好函数,就可以实现数据通信。
TCP提供了stream和datagram两种通信机制,所以socket分这两种。
stream的类型是SOCK_STREAM,采用TCP协议,TCP协议在计算机网络中是安全可靠的有连接的协议。datagram的类型是SOCK_DGRAM,采用的是UDP协议,UDP是不可靠的协议,现在在实际应用开发中,主要采用的是TCP。
服务端主要流程:创建socket—bind绑定ip和port—listen监听客户端连接请求—accept接受连接----数据传输----close关闭连接

 int listenfd;
    listenfd=socket(AF_INET,SOCK_STREAM,0);//在socket编程中,AF_INET是必须的,等同于固定搭配
    //socket创建成功后如果返回值是-1的话,说明创建失败,为0的时候就是创建成功
    if(listenfd==-1)
    {
        printf("socket create fail\n");
        return -1;
    }
struct sockaddr_in serveraddr;//定义一个用来处理网络通信的数据结构,sockaddr_in分别将端口和地址存储在两个结构体中
    //sin_family协议族
    memset(&serveraddr,0,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //serveraddr.sin_addr.s_addr=atoi(argv[1]);// specify ip address
    serveraddr.sin_port=htons(atoi(argv[1]));//specify port
    //printf("%s %s\n",argv[1],argv[2]);
    if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))!=0)
    {
        printf("bind failed \n");
        return -1;
    }

INADDR_ANY 表示监听0.0.0.0地址,socket只绑定端口,不绑定本主机的某个特定ip,让路由表决定传到哪个ip(0.0.0.0地址表示所有地址、不确定地址、任意地址)(一台主机中如果有多个网卡就有多个ip地址)
htons()把short型值转成按网络字节顺序排列的short型值
htonl()把long型值转成按网络字节顺序排列的long型值
假设你已经有了一个sockaddr_in结构体ina,你有一个IP地址"132.241.5.10" 要储存在其中,你就要用到函数inet_addr(),将IP地址从 点数格式转换成无符号长整型。使用方法如下:

ina.sin_addr.s_addr = inet_addr(“132.241.5.10”);

 if(listen(listenfd,5)!=0)
    {
        printf("Listen failed\n");
        close(listenfd);
        return -1;
    }

backlog 5 是未经过处理的连接请求队列可以容纳的最大数目。

    int clintfd;//socket for client
    int socklen=sizeof(struct sockaddr_in);
    struct sockaddr_in client_addr;
    clintfd=accept(listenfd,(struct sockaddr*)&client_addr,(socklen_t *)&socklen);
    if(clintfd==-1)
        printf("connect failed\n");
    else
        printf("client %s has connnected\n",inet_ntoa(client_addr.sin_addr));
   inet_ntoa将网络地址转换成“.”点隔的字符串格式。
    char buffer[1024];
    while (1)
    {
    int iret;
    memset(buffer,0,sizeof(buffer));
    iret=recv(clintfd,buffer,sizeof(buffer),0);
    if (iret<=0) 
    {
       printf("iret=%d\n",iret); break;  
    }
    printf("receive :%s\n",buffer);
 
    strcpy(buffer,"ok");//reply cilent with "ok"
    if ( (iret=send(clintfd,buffer,strlen(buffer),0))<=0) 
    { 
        perror("send"); 
        break; 
    }
    printf("send :%s\n",buffer);
  }
    // 6th close socket
    close(listenfd); close(clintfd);

对于服务端来说有两个socket,这里该如何理解呢?
一开始socket函数, 不管在客户端还是在服务端, 创建的都是主动socket, 但是在服务端经过listen(), 后把其转变为listen_socket_fd(被动监听socket),经过accept()后转变为connect_socket_fd(已连接socket).
在转变为connect_socket_fd之前, 都是同一个socket, 只不过是socket的状态改变了, 但是服务端经过accept()后返回的socket是新的socket, 用于连接后的read()/write()
假设只用一个socket完成整个过程. 那么这个socket就会一直被占用, 而不能被另外的客户端请求, 造成了服务端的性能极其低下, 如果没有存储后面的客户端请求, 就会被错过而丢弃, 因为当前的socket正在与当前一个客户端的socket建立连接.

客户端 socket-connect

 struct sockaddr_in servaddr;
  memset(&servaddr,0,sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(atoi(argv[2])); // server's port
  servaddr.sin_addr.s_addr=inet_addr(argv[1]);//server's ip
  if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0)  // send request to server for connection
  { 
      perror("connect"); 
      close(sockfd); 
      return -1; 
  }

多进程的(一个服务端服务多个客户端)
在这里插入图片描述
具体实现就是:在accept部分增加一个外层的循环,
在这里插入图片描述子进程执行完之后就return 0或者exit(0),直接退出去。
还有一个问题就是:查看打开的进程编号可以发现,父进程和子进程文件描述符一样的。对于父进程来说,只需要监听连接,不需要连接后的fd;对子进程来说,listenfd也是不需要的。但是fork会生成一份副本,导致父子进程都有listenfd和connectfd,所以可以在父进程中关掉connectfd,子进程中关掉listenfd。为什么要这么做,因为fd是一种资源,维护一个fd不难,但是很多客户端就会有很多冗余的fd,造成资源浪费。而且一个进程能打开的fd是有限的。

多进程服务程序的退出
在这里插入图片描述
子进程收到退出信号(ctrl+c),在子进程设置signal(2,childexit),signal(15,childexit)。然后子进程关闭客户端的fd再退出。
父进程会关闭listenfd,然后通知所有子进程退出,然后退出。

TCP长连接和心跳机制的实现
短连接:
短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接(管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段);
连接→数据传输→关闭连接;
所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持(不发生RST包和四次挥手)。
连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接(一个TCP连接通道多个读写通信);
长连接多用于操作频繁(读写),点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接(http1.0只支持短连接,1.1keep alive 带时间,操作次数限制的长连接),因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好;

具体实现:
服务端和客户端约定超时时间,假设35秒;
如果服务端35秒没收到报文,认为客户端异常,主动关闭;
客户端35秒内没有任何业务,发送心跳报文,以维持连接。

客户端在空闲时发送心跳报文,服务端的读函数增加一个超时参数,超时就断开连接,不超时就回复成功。

实现文件的上传和下载功能、异步通信机制实现快速传输。

主要包含:文件传输的服务端模块(支持上传下载) 文件上传的客户端,文件下载的客户端。
客户端分成两个是因为让程序结构更简单,模块化;服务端不分开因为它是网络服务程序,分成两个的话就要两个监听的端口,配置网络参数更麻烦,比如路由器防火墙。

文件上传客户端:登录(意义在于协商与服务端协商文件传输参数,最重要参数就是文件存放目录,客户端的A目录存在服务端的B目录)
客户端获取本地目录的文件清单,假设有100个文件,一个循环,每次先传文件信息(名字,大小,时间),再传内容。
结束后客户端休息几秒,再重新获取本地目录的文件清单。

注意:用于系统内部文件传输,所以客户端程序常驻内存,每隔几秒就传输一次。客户端上传成功后直接删除本地文件就可以。

定义一个结构体存储心跳,目录等信息。
在这里插入图片描述

服务端只要之前的参数就可以,客户端通过登录报文将更多的参数传到服务端。

在这里插入图片描述

服务端再修改相应的代码。处理登录报文,如果是1,就完成上传功能主函数。
在这里插入图片描述
首先服务端调用_xmltoarg方法解析登录报文,如果是1或者2,发送ok给客户端,否则发送failed给客户端。如果登陆失败(美没收到服务端回应),直接退出。
如果类型为1,调用RecvFilesMain()

void RecvFilesMain()
{
   while(true)
   { 
        memset(recvbuf,0,sizeof(recvbuf));
         memset(sendbuf,0,sizeof(sendbuf));
         如果接收客户端的报文read失败(超时),记录日志,return;
         如果接收缓存内容是心跳报文,给客户端回复ok;
         处理上传文件的请求报文
         }
   }

客户端文件信息的上传怎么实现?
在这里插入图片描述
服务端怎么处理这些信息
在这里插入图片描述
传输文件的内容
sendfile函数实现。参数有连接的socketfd,文件名,文件大小。


在这里插入图片描述

异步通讯三种实现方法:
1、多进程:服务端客户端后,fork一个子进程,子进程负责接收信息,父进程发送信息,
2、多线程。
3、I/O复用技术

同步的话客户端发送报文,要等到接受ok再发送第二个,10000个数据需要6秒。异步的话,父进程发送报文,子进程接受ok的成功信息,1秒。

如果是10万的话,同步每秒2000左右,异步每秒8万左右。

I/O复用就是没有数据的话不等待,直接返回。每秒差不多6万,低一点,原因就是有数据的话会等待数据搞完再发送,当然低一点。

Qt详解实现TCP文件传输例子(文件下载和上传)附源码 变量qint64 payloadSize用来控制每次文件读取的字节数,progressByte用来存储发送的进度,我这里一次只发送1024个字节,因为区域网传输太快了,文明小传输过程不明显,你们可以调大小,比如1024*64个字节。收到服务器发送的文件信息消息后,进行读取,获取文件名,文件大小,用文件类对象进行存储,新建准备写入一个要下载的文件,准备工作完成后,向服务器发送获取文件数据的消息。传输文件信息时,需要获取要发送的文件信息,如文件名,文件大小等,然后将这些信息发送给客户端。//是否正在下载标识。 阅读详情

相关推荐

网络编程:用tcp实现文件传输

tcp实现文件传输 文件发送端(tcp客户端) 1.网络链接 2.发送文件信息(文件名称, 文件大小) 3.发送文件内容(分段发送) 文件接收端 (tcp服务器) 1.网络初始化监听 2.接收文件信息(创建一个空文件准备接收数据) 3.接收文件内容(分段接收,计算接收得长度==文件大小) 完整代码: 发文件 /* 1. 文件发送端(tcp客户端) 1.网络链接 2.发送文件信息(文件名称, 文件大小) 3.发送文件内容(分段发送) */ #include <stdio.h> #i

qq_42343682的博客 7432

C使用TCP协议进行文件传输

tcp文件传输

weixin_53497899的博客 3209

基于C语言的TCP协议文件传输系统实现

TCP头部有个16位校验和字段,但它保护的范围超乎想象——不仅包括TCP头和数据,还有所谓的“伪头部”(源IP、目的IP、协议号、TCP长度)。这是为了防止IP层转发时改了地址却没更新校验和的情况。更绝的是,现代网卡基本都支持checksum offload,也就是校验和计算交给硬件完成。但这带来一个调试难题:你在Wireshark里看到的校验和可能是无效的!因为抓包发生在硬件计算之前。要验证真正的校验和,得在另一台机器上看。

weixin_35578748的博客 810

第三篇、TCP文件传输

TCP文件传输

weixin_45796249的博客 4372

计算机网络课程设计--基于TCP协议文件传输系统

设计并实现基于 TCP 协议文件传输系统,包含客户端和服务器端,支持文件上传、下载、列表查询及删除功能,确保核心功能完整可用。TCP Socket 关键方法:bind()、listen()、accept()(服务器端),connect()(客户端)文件操作:实现upload_file(上传)、download_file(下载)、delete_file(删除)功能。命令处理:支持list(列表查询)、upload(上传)、download(下载)、delete(删除)命令。

sjj_1234567的博客 927

QT下基于TCP协议的多线程文件传输系统实现

QTcpSocket是Qt框架中提供的一种网络通信类,它封装了TCP协议的细节,使得开发者能够专注于应用层的逻辑设计,而不必担心底层的通信机制。QTcpSocket支持阻塞和非阻塞模式,以及持续连接和断线重连等特性。TCP/IP协议栈,也被称作互联网协议套件,是实现网络通信的标准化框架。在该框架中,信息在不同设备之间传输时会经过不同层次的处理。TCP/IP被划分为四个层次:链路层、网络层、传输层和应用层。链路层:负责在相邻节点间的线路上无差错地传送以帧为单位的数据。网络层。

weixin_32102617的博客 964

基于TCP协议开发文件传输系统

简介:基于TCP协议开发文件传输系统,搭建多进程网络服务程序框架,实现TCP长连接心跳机制、文件上传与下载、异步通信实现快速传输

玖玖玖 1843

构建跨平台文件传输系统TCP协议实战

传输控制协议TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它被设计用来保证数据传输的准确性和顺序性,确保数据包能够在网络中安全可靠地传输到目的地。

weixin_30923011的博客 768

基于TCP协议的聊天与文件传输系统设计与实现

本文介绍了一个基于Java开发的局域网即时通讯系统,采用客户端-服务器架构实现多人聊天和文件传输功能。系统支持群聊/私聊(@用户方式)、各类文件传输及媒体文件自动播放(图片/音频/视频)。技术实现上使用TCP协议保证传输可靠性,通过Swing处理文件选择,集成JLayer和VLC实现媒体播放功能。核心模块包括文件传输工具类、服务器端连接管理及客户端交互界面,具备智能文件识别、图片自适应缩放等特色功能。系统需JDK8+环境运行,支持多客户端同时连接。作者总结该项目巩固了TCP网络编程实践,未来可改进方向包括图

m0_73706476的博客 421

Linux 基于TCP协议文件传输系统

文章目录1、服务端2、客户端(上传文件)3、makefile 1、服务端 #include "_public.h" CLogFile logfile; CTcpServer TcpServer; // 程序运行的参数结构体。 struct st_arg { int clienttype; // 客户端类型,1-上传文件;2-下载文件。 char ip[31]; // 服务端的IP地址。 int port; // 服

weixin_45715405的博客 1784

Linux基于socket 和 tcp协议的FTP文件传输系统

Linux 基于server和client的FTP文件项目 功能需求: 远程操作: ①获取服务器的文件: get xxx ②显示服务器有哪些文件: ls ③进入服务器某文件夹: cd xxx ④上传文件到服务器: put xxx ⑤打印当前服务器路径: pwd ⑥退出服务器: quit 本地操作: ①查看客户端本地文件: lls ②进入客户端文件夹: lcd 基本思路

qq_42102650的博客 629

IM系统核心难题实战:用Netty解决TCP粘包/半包,并设计一个高效的心跳与文件传输协议

本文深入探讨IM系统开发中的核心网络通信问题,包括TCP粘包/半包现象及其解决方案,以及如何利用Netty设计高效的心跳机制和文件传输协议。通过私有协议实现、动态心跳优化和分片传输技术,提升即时通讯系统的稳定性和性能。

weixin_30875157的博客 594

MyQQ即时通讯系统VC源码全解析(含服务端/客户端/屏幕抓取/文件传输/TCP-UDP协议

MyQQ采用经典的C/S(客户端/服务器)架构,整体分为网络层、业务逻辑层、UI交互层三大模块。网络层基于Winsock实现TCP/UDP协议通信;业务逻辑层处理消息路由、用户认证、文件传输等核心功能;UI层依托MFC框架构建可视化界面,实现消息窗口、联系人列表等组件。各层通过接口解耦,提升可维护性。为了准确解析每条消息,MyQQ采用“固定头部 + 可变体部”的二进制协议格式:#pragma pack(push, 1) // 强制1字节对齐// 消息体长度(不包括头)

weixin_42443533的博客 904

基于TCP协议的局域网内高性能文件传输系统设计与实现

系统整体设计思路及上传、下载文件的设计方案、断点续传的原理及设计、秒传的原理及设计、数据库设计API编程与shell脚本的设计、大文件传输原理及实现、使用sendfile()实现“零拷贝”机制、实现高并发——负载均衡技术浅析

ZY-JIMMY 5236

QT多线程TCP文件传输系统实战指南

本文还有配套的精品资源,点击获取 简介:QT框架是一个跨平台的应用程序开发框架,拥有丰富的API,能够构建功能强大的应用程序。本主题深入探讨了在QT框架中,基于TCP协议的多线程文件传输系统的实现。涵盖QT框架基础、TCP协议、QT中的网络编程、多线程编程、文件传输实现、错误处理以及连接管理。此外,还包含欢迎文档和源代码压缩包,以帮助开发者学习如何在QT中实现TCP文件传输...

weixin_35516273的博客 2105

TCP文件传输系统设计与实现

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它在IP协议基础上提供端到端的数据传输服务,确保数据包按照正确的顺序到达,并在必要时进行重传,以此来提供可靠的数据传输文件传输的基本原理涉及到数据的打包、传输、接收和重组。发送端的文件传输系统会将文件分割成数据包,这些数据包经过网络传输,到达接收端之后,接收端的系统会负责将这些数据包重新组合成原始文件。整个过程需要确保数据的完整性和顺序性。

weixin_28681379的博客 436

TCP/UDP协议实现多人QQ聊天系统

传输层是计算机网络协议栈中的重要层次,位于应用层和网络层之间。传输层的主要职责是为运行在不同主机上的应用进程提供端到端的通信服务。一个多人在线聊天系统的主要功能需求可以分为以下几点:用户注册与登录:系统需要提供用户注册功能,包括用户身份验证和授权。用户可以使用用户名和密码登录系统,而管理员可以维护用户账号信息。即时消息传输:支持文本消息的即时传输,并能够实现消息的加密和解密,确保通信的安全性。消息持久化。

weixin_35414484的博客 680

QT文件传输系统实现

跨平台软件开发是软件工业的重要方向之一,它允许开发者使用一套代码库,为多个操作系统构建应用程序。QT是一个广泛使用的跨平台框架,它为开发者提供了一套完整的工具集和库,以实现不同操作系统下的图形用户界面(GUI)应用开发。文件传输系统是一种将文件从一个位置传输到另一个位置的机制。在计算机网络中,文件传输涉及将文件从一台计算机发送到网络上的另一台计算机,通常涉及多个网络协议传输方法。文件传输对于数据共享、备份、更新和分发都至关重要。它支持多种业务流程,比如软件分发、数据备份、媒体共享等。

weixin_31185473的博客 1134
上一篇: 开发不停机的服务程序
下一篇: 数据库主从复制和读写分离
explore翔
博客等级 码龄6年 50粉丝 293原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值