当前位置: 首页 > news >正文

基于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 addressserveraddr.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 clientint 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");elseprintf("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 socketclose(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 portservaddr.sin_addr.s_addr=inet_addr(argv[1]);//server's ipif (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万,低一点,原因就是有数据的话会等待数据搞完再发送,当然低一点。

相关文章:

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

最简单的一对一的服务端网络端通信(socket) Socket&#xff08;IP地址&#xff1a;端口号&#xff09;&#xff0c;例如&#xff1a;如果IP地址是210.37.145.1&#xff0c;而端口号是23&#xff0c;那么得到套接字就是(210.37.145.1:23) socket可以理解成计算机提供给程序员的接…...

Linux定时备份MySql数据库

一、创建文件 cd / mkdir mysqlbackup vi mysqlbackup.sh然后将下面的代码更改后复制上去即可。 #!/bin/bash mysqldump -uroot -ppassword database > /mysqlbackup/database__$(date %Y%m%d_%H%M%S).sqlpassword指的是MySql的密码&#xff0c;database指的是所要备份的…...

JavaScript prototype(原型对象)

JavaScript 的原型&#xff08;prototype&#xff09;是 JavaScript 中的一个重要概念。它是一种特殊类型的对象&#xff0c;每个 JavaScript 对象都有一个原型对象。原型对象在 JavaScript 中起着非常重要的作用。本文将详细介绍 JavaScript 原型对象的作用和在实际工作中的用…...

pytorch各种版本最简单安装,不用自己安装cuda cudnn

pytorch各种版本 pip 安装命令 查看官网 https://pytorch.org/get-started/previous-versions/ conda pytorch 安装 1、安装conda&#xff0c; 2、创建并并激活虚拟环境 - conda create -n pytorch_1.7 python3.7 - conda activate pytorch_1.7 3、虚拟环境中 pip 安装想要的…...

订单超时处理方案介绍

在电商场景下&#xff0c;一个订单流程中有许多环节要用到超时处理&#xff0c;包括但不限于&#xff1a; 买家超时未付款&#xff1a;比如超过15分钟没有支付&#xff0c;订单自动取消。 商家超时未发货&#xff1a;比如商家超过1个月没发货&#xff0c;订单自动取消。 买家…...

Blackbox-Exporter对服务进行探活

前言 blackbox-exporter会对HTTP、HTTPS、DNS、TCP、ICMP和gRPC上的端点进行黑盒探测。 Blackbox-Exporter blackbox-exporter暴露两个Metrics指标接口&#xff0c;分别是 /metrics、/probe&#xff0c;两个接口返回不同监控目标的指标 Metrics接口 返回exporter的构建信息…...

react-redux

Redux 是js容器&#xff0c;用于进行全局的 状态管理它可以用在react, angular, vue等项目中, 但基本与react配合使用三大核心&#xff1a; 单一数据源 整个应用的state被存储在一棵 object tree中&#xff0c;并且这个 object tree只存在于一个唯一的 store 中 State是只读的…...

算法刷刷刷| 回溯篇| 子集问题大集合

78.子集 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1…...

合并两个有序数组-力扣88-java

一、题目描述给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。注意&#xff1a;最终&#xff0c;合…...

2022「大厂可观测」重磅回顾,12场直播,15位技术大咖洞见可观测

回首2022年&#xff0c;注定是意义非凡的一年。新冠疫情继续肆虐全球&#xff0c;中国疫情全面放开&#xff0c;神舟十四号与神舟十五号成功会师&#xff0c;俄乌冲突带来深远影响&#xff0c;阿根廷再次问鼎世界杯梅西圆梦&#xff0c;英国女王逝世......件件事都备受关注。 …...

CMMI-配置管理(CM)

一、概述配置管理&#xff08;Configuration Management&#xff0c; CM&#xff09;的目的在于使用配置识别、配置控制、配置状态记录与报告以及配置审计&#xff0c;来建立并维护工作产品的完整性。1、简介“配置管理”过程域涉及以下活动&#xff1a;• 识别所选工作产品的配…...

网络编程套接字Socket

一.什么是网络编程网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数据传输&#xff09;。二.为什么要实现网络编程我们通过网络编程可以在网络中获取资源&#xff0c;实质是通过网络&#xff0c;获…...

Linux进程概念(二)

进程状态1.阻塞和挂起2.R运行状态和S睡眠状态3.T停止状态4.X死亡状态和Z僵尸状态&#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列专栏&#xff1a;【Linux的学习】 &#x1f4dd;&#x1f4dd;本…...

墨天轮【第二届数据库掌门人论坛】圆满收官 | 含嘉宾精彩观点回顾

2月10日上午&#xff0c;墨天轮【2023春季发布会暨第二届数据库掌门人论坛】盛大开启&#xff0c;本次活动的主题为“新征程&#xff0c;向未来”&#xff0c;共包含2022年度中国数据库颁奖盛典、2022年度行业发展报告发布以及第二届数据库掌门人论坛三项议程。华为云数据库服务…...

Redis之集群搭建

redis的集群模式简介&#xff1a; redis的集群模式中可以实现多个节点同时提供写操作&#xff0c;redis集群模式采用无中心结构&#xff0c;每个节点都保存数据&#xff0c;节点之间互相连接从而知道整个集群状态。 集群搭建步骤如下 (一台服务器模拟多台服务器) 1.创建6个配置…...

31-Golang中的二维数组

二维数组的使用方式 使用方式一&#xff1a;先声明/定义再赋值 1.语法&#xff1a;var数组名 [大小] [大小]类型2.比如&#xff1a;var arr [2] [3]int,再赋值 package main import ("fmt" )func main() {//定义/声明数组var arr [4][6]int//赋初值arr[1][2] 1ar…...

<<Java开发环境配置>>6-SQLyog安装教程

一.SQLyog简介: SQLyog 是一个快速而简洁的图形化管理MySQL数据库的工具&#xff0c;它能够在任何地点有效地管理你的数据库&#xff0c;由业界著名的Webyog公司出品。使用SQLyog可以快速直观地让您从世界的任何角落通过网络来维护远端的MySQL数据库。 二.SQLyog下载: 下载地址…...

MySQL 中的 distinct 和 group by 哪个效率更高

先说大致的结论&#xff08;完整结论在文末&#xff09;&#xff1a;在语义相同&#xff0c;有索引的情况下&#xff1a;group by和distinct都能使用索引&#xff0c;效率相同。在语义相同&#xff0c;无索引的情况下&#xff1a;distinct效率高于group by。原因是distinct 和 …...

计算机相关专业毕业论文选题推荐

计算机科学以下是我推荐的20个计算机科学专业的本科论文选题&#xff1a;基于机器学习的推荐算法研究与实现基于区块链技术的数字身份认证方案设计与实现基于深度学习的图像识别技术研究与应用基于虚拟现实技术的教育培训平台设计与实现基于物联网技术的智能家居系统研究与开发…...

网络编程套接字之TCP

文章目录一、TCP流套接字编程ServerSocketSocketTCP长短连接二、TCP回显服务器客户端服务器客户端并发服务器UDP与TCP一、TCP流套接字编程 我们来一起学习一下TCP socket api的使用&#xff0c;这个api与我们之前学习的IO流操作紧密相关&#xff0c;如果对IO流还不太熟悉的&am…...

网络与串口调试工具TCPCOM

TCPCOM&#xff0c;网络与串口二合一调试助手&#xff0c;将网络调试助手与串口调试助手合二为一&#xff0c;绿色软件&#xff0c;简单高效。【软件特色】 1. 支持中英文双语言&#xff0c;自动根据操作系统环境选择系统语言类型&#xff1b; 2. 支持ASCII/Hex发送,发送和接收…...

数据库常用命令

文章目录1. 数据库操作命令1.进入数据库2.查看数据库列表信息3.查看数据库中的数据表信息2.SQL语句命令1. 创建数据表2. 基本查询语句3. SQL排序4. SQL分组统计5. 分页查询6. 多表查询7.自关联查询8.子查询1. 数据库操作命令 1.进入数据库 mysql -uroot -p2.查看数据库列表信…...

PTA复习

函数 6-1 学生类的构造与析构 #include<bits/stdc.h> using namespace std; class Student {int num;string name;char sex; public:Student(int n,string nam,char s):num(n),name(nam),sex(s){cout<<"Constructor called."<<endl;}void display…...

TypeScript 学习之接口

接口&#xff1a;对值所具有的结构进行类型检查&#xff0c;称为“鸭式变型法”或“结构性子类型化” 基本使用 interface LabelledValue {label: string; }function printLabel(labelledObj: LabelledValue) {console.log(labelledObj.label); }let myObj {size: 10, label:…...

原码反码补码

在计算机中&#xff0c;负数都是以补码的形式存放的&#xff0c; 正数的原码、反码、补码完全一致。 原码&#xff1a;指的是正数的二进制或负数的二进制&#xff0c; 负数的二进制&#xff08;原码&#xff09;&#xff0c;其实就是在正数的二进制的最高位前面加一个符号位 1。…...

大数据选股智能推荐系统V1.0-1

很长时间没有发布博客了&#xff0c;这段时间个人确实有点忙。另外一方面在这段时间我也没有闲着。自己研发了一套大数据选股的智能推荐系统。废话不说&#xff0c;我们先来看这套系统&#xff1a;登录页面&#xff1a;&#xff08;技术点&#xff1a;验证码的生成&#xff09;…...

调研生成GIF表情包之路

调研阶段 gifshot.js合成GIF 可以从媒体流、视频或图像创建动画 GIF 的 JavaScript 库。 csdn地址&#xff1a;https://blog.csdn.net/qq_16494241/article/details/125717405 分解GIF图片、合成GIF图片 两步走&#xff1a; 1、分解GIF图片 libgif-js&#xff1a;JavaScrip…...

【RocketMQ】源码详解:生产者启动与消息发送流程

消息发送 生产者启动 入口 : org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#start(boolean) 生产者在调用send()方法发送消息之前,需要调用start进行启动, 生产者启动过程中会启动一些服务和线程 启动过程中会启动MQClientInstance, 这个实例是针对一个项…...

信息安全(一)

思维导图 一、AES加解密 1.概述 1.1 概念 AES&#xff1a; 高级加密标准&#xff08;Advanced Encryption Standard&#xff09;是一种对称加密的区块加密标准。 &#xff08;1&#xff09;替代DES的新一代分组加密算法 &#xff08;2&#xff09;支持三种长度密钥&#x…...

企业多会场视频直播(主会场、分会场直播)实例效果

阿酷TONY 2023-2-16 长沙 活动直播做多会场切换功能&#xff08;主会场、分会场、会场一、会场二、会场三自由切换&#xff09; 企业多会场视频直播&#xff08;主会场、分会场直播&#xff09;实例效果 特点&#xff1a;支持PC端&#xff0c;也支持移动端观看&#xff0c;会…...

顺德网站建设基本流程/武汉网站开发公司

--> Servelet: 用于接收请求(客户端,浏览器),做出响应的,服务器端的,java类 --> ServletLogin -- Web项目服务器响应的Java实现 package com.dragon.java.servlet;import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException…...

潍坊 网站建设/各大引擎搜索入口

上半年流畅度的新机排名&#xff0c;哇&#xff01;第一名居然是这款2019-05-11 22:26:4510点赞6收藏29评论要了解更多流行资讯、玩机技巧、数码体验、科普深扒&#xff0c;点击右上角关注我-----------2019年到现在已经过半了&#xff0c;各大手机厂商的新机发布热潮也慢慢降了…...

自己做qq代刷网站要钱吗/自媒体怎么做

大家好,我是小马老师。 本文介绍python统计并输出CNA结构分析结果。 Ovito CNA模块可以分析不同时刻的晶体结构,但是在ovito软件中的分析结果不方便直接绘图输出,因此本文给出一个python脚本,运行之后可以直接绘制不同晶体结构的比例图。 程序使用方法: 复制以下pyth…...

wordpress ftp密码/河北网站优化公司

淘宝商家开直通车一直都希望讲究高效的开&#xff0c;而不是开车还带不来转化&#xff0c;一直在纠结要不要继续开下去。开直通车如果说有很多错误和操作的误区&#xff0c;只凭借自己的理解和猜想去开车&#xff0c;那么必然会有很多问题产生。 开直通车误区一&#xff1a;投…...

龙华做网站的公司/百度收录接口

[TOC] 1. 什么是碎片 ​ 碎片&#xff0c;是Android 3.0&#xff08;API 11&#xff09;提出的&#xff0c;为了兼容低版本&#xff0c;support-v4库中也开发了一套Fragment API&#xff0c;最低兼容Android 1.6。 过去support-v4库是一个jar包&#xff0c;24.2.0版本开始&…...

轻量级服务器wordpress密钥/搜索引擎优化的要点

问题所处环境&#xff1a;IIS 7.5, ASP.NET 4.0, 应用程序池(Application Pool)运行于集成模式(Integrated)。 今天一位园友向我们反馈用网摘收藏博客文章LINQ那些事(9)-解析Table<T>.Attach引发的异常和解决方法时出错&#xff08;注意&#xff1a;文章标题中有尖括号&a…...