Socket通信总结(附C++实现)

浅谈socket传输文件速率优化 前言 最近有个需求,就是在需要提升换机助手的传输文件的传输速度。先来看看什么是换机助手。 一般厂家的换机助手都长这个样子,就是将旧手机的一些数据拷贝到新手机上去。数据一般包括:联系人,短信,壁纸,图片,音乐,视屏,文件,设置项等等。然后传输都是使用的wifi 或者wifi 直连连接后通过socket 协议去传输文件。这篇文章重在说明如何提高socket的传输速度。下面先说几个概念: 1.wifi 和wifi p2p(直连) Wi-Fi Direct是一种全新的技术,即使在没有传统的Wi-Fi网络或Wi- 阅读详情

文章目录[隐藏]

       因为项目需要,服务端需要一个SOCKET来接收客户端的请求,好吧,没办法度娘哇,结果很多都是linux的例子,功夫不负有心人啊,终于找到个demo,并且客户端代码详尽,记录之,以便以后查看。

一、Socket是什么

   Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

 

二、一些基本概念

  1. TCP/IP
               TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。
               在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
               在传输层中有TCP协议与UDP协议。
               在应用层有:TCP包括FTP、HTTP、TELNET、SMTP等协议
               UDP包括DNS、TFTP等协议

  2. 短连接:
               连接->传输数据->关闭连接
               HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

  3. 长连接:
               连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。
               长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。

  4. http的长连接:
               HTTP也可以建立长连接的,使用Connection:keep-alive,HTTP 1.1默认进行持久连接。HTTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持(貌似最新的 http1.0 可以显示的指定 keep-alive),但还是无状态的,或者说是不可以信任的。
    什么时候用长连接,短连接?
               长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
    而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
               总之,长连接和短连接的选择要视情况而定

  5. 发送接收方式
    1、异步 

           报文发送和接收是分开的,相互独立的,互不影响。这种方式又分两种情况: 
           (1)异步双工:接收和发送在同一个程序中,由两个不同的子进程分别负责发送和接收 
           (2)异步单工:接收和发送是用两个不同的程序来完成。 
    2、同步 
           报文发送和接收是同步进行,既报文发送后等待接收返回报文。 同步方式一般需要考虑超时问题,即报文发出去后不能无限等待,需要设定超时时间,超过该时间发送方不再等待读返回报文,直接通知超时返回。
           在长连接中一般是没有条件能够判断读写什么时候结束,所以必须要加长度报文头。读函数先是读取报文头的长度,再根据这个长度去读相应长度的报文。  

三、java socket建立连接的过程  

 

        1、 首先调用Socket类的构造函数,以服务器的指定的IP地址或指定的主机名和指定的端口号为参数,创建一个Socket流,在创建Socket流的过程中包含了向服务器请求建立通讯连接的过程实现。
       2、 建立了客户端通讯Socket后。就可以使用Socket的方法getInputStream()和getOutputStream()来创建输入/输出流。这样,使用Socket类后,网络输入输出也转化为使用流对象的过程。
       3、 使用输入输出流对象的相应方法读写字节流数据,因为流连接着通讯所用的Socket,Socket又是和服务器端建立连接的一个端点,因此数据将通过连接从服务器得到或发向服务器。这时我们就可以对字节流数据按客户端和服务器之间的协议进行处理,完成双方的通讯任务。
       4、 待通讯任务完毕后,我们用流对象的close()方法来关闭用于网络通讯的输入输出流,在用Socket对象的close()方法来关闭Socket。

四、Socket 通信示例

 

       主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。

五、建立通信链路

       当客户端要与服务端通信,客户端首先要创建一个 Socket 实例,操作系统将为这个 Socket 实例分配一个没有被使用的本地端口号,并创建一个包含本地和远程地址和端口号的套接字数据结构,这个数据结构将一直保存在系统中直到这个连接关闭。在创建 Socket 实例的构造函数正确返回之前,将要进行 TCP 的三次握手协议,TCP 握手协议完成后,Socket 实例对象将创建完成,否则将抛出 IOException 错误。
       与之对应的服务端将创建一个 ServerSocket 实例,ServerSocket 创建比较简单只要指定的端口号没有被占用,一般实例创建都会成功,同时操作系统也会为 ServerSocket 实例创建一个底层数据结构,这个数据结构中包含指定监听的端口号和包含监听地址的通配符,通常情况下都是“*”即监听所有地址。之后当调用 accept() 方法时,将进入阻塞状态,等待客户端的请求。当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构,该套接字数据的信息包含的地址和端口信息正是请求源地址和端口。这个新创建的数据结构将会关联到 ServerSocket 实例的一个未完成的连接数据结构列表中,注意这时服务端与之对应的 Socket 实例并没有完成创建,而要等到与客户端的三次握手完成后,这个服务端的 Socket 实例才会返回,并将这个 Socket 实例对应的数据结构从未完成列表中移到已完成列表中。所以 ServerSocket 所关联的列表中每个数据结构,都代表与一个客户端的建立的 TCP 连接。

       备注:

        Windows 下单机最大TCP连接数

           调整系统参数来调整单机的最大TCP连接数,Windows 下单机的TCP连接数有多个参数共同决定:
           以下都是通过修改注册表[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
           1.    最大TCP连接数        TcpNumConnections
           2.    TCP关闭延迟时间    TCPTimedWaitDelay    (30-240)s        
           3.    最大动态端口数   MaxUserPort  (Default = 5000, Max = 65534) TCP客户端和服务器连接时,客户端必须分配一个动态端口,默认情况下这个动态端口的分配范围为 1024-5000 ,也就是说默认情况下,客户端最多可以同时发起3977 个Socket 连接    
           4.   最大TCB 数量   MaxFreeTcbs系统为每个TCP 连接分配一个TCP 控制块(TCP control block or TCB),这个控制块用于缓存TCP连接的一些参数,每个TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就说,每个TCP连接会占用 1KB 的系统内存。非Server版本,MaxFreeTcbs 的默认值为1000 (64M 以上物理内存)Server 版本,这个的默认值为 2000。也就是说,默认情况下,Server 版本最多同时可以建立并保持2000个TCP 连接。
           5.   最大TCB Hash table 数量   MaxHashTableSize TCB 是通过Hash table 来管理的。这个值指明分配 pagepool 内存的数量,也就是说,如果MaxFreeTcbs = 1000 , 则 pagepool 的内存数量为 500KB那么 MaxHashTableSize 应大于 500 才行。这个数量越大,则Hash table 的冗余度就越高,每次分配和查找 TCP  连接用时就越少。这个值必须是2的幂,且最大为65536.

 

六、服务端代码:

[cpp] view plaincopy

  1. /*     
  2.  * testSocketService.c     
  3.  *     
  4.  *  Created on: 2012-8-16     
  5.  *      Author: 皓月繁星     
  6.  */  
  7. #include <WINSOCK2.H>   
  8. #include <stdio.h>     
  9.                     
  10. #define PORT           5150    
  11. #define MSGSIZE        1024    
  12.                    
  13. #pragma comment(lib, "ws2_32.lib")      
  14.                    
  15. int main()      
  16. {      
  17.     WSADATA wsaData;      
  18.     SOCKET sListen;      
  19.     SOCKET sClient;      
  20.     SOCKADDR_IN local;      
  21.     SOCKADDR_IN client;      
  22.     char szMessage[MSGSIZE];      
  23.     int ret;      
  24.     int iaddrSize = sizeof(SOCKADDR_IN);      
  25.     WSAStartup(0x0202, &wsaData);      
  26.                    
  27.     sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      
  28.                    
  29.     local.sin_family = AF_INET;      
  30.     local.sin_port = htons(PORT);      
  31.     local.sin_addr.s_addr = htonl(INADDR_ANY);      
  32.     bind(sListen, (struct sockaddr *) &local, sizeof(SOCKADDR_IN));      
  33.                    
  34.     listen(sListen, 1);      
  35.                    
  36.     sClient = accept(sListen, (struct sockaddr *) &client, &iaddrSize);      
  37.     printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr),      
  38.             ntohs(client.sin_port));      
  39.                    
  40.     while (TRUE) {      
  41.         ret = recv(sClient, szMessage, MSGSIZE, 0);      
  42.         szMessage[ret] = '\0';      
  43.         printf("Received [%d bytes]: '%s'\n", ret, szMessage);      
  44.     }      
  45.     return 0;      
  46.   }  

 

七、客户端代码

[cpp] view plaincopy

  1. /*     
  2.  * testSocketClient.c     
  3.  *     
  4.  *  Created on: 2012-8-16     
  5.  *      Author: 皓月繁星     
  6.  */  
  7. #include <WINSOCK2.H>   
  8. #include <stdio.h>     
  9.                     
  10. //定义程序中使用的常量      
  11. #define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址      
  12. #define PORT           5150         //服务器的端口号      
  13. #define MSGSIZE        1024         //收发缓冲区的大小      
  14. #pragma comment(lib, "ws2_32.lib")      
  15.                    
  16. int main()      
  17. {      
  18.     WSADATA wsaData;      
  19.     //连接所用套节字      
  20.     SOCKET sClient;      
  21.     //保存远程服务器的地址信息      
  22.     SOCKADDR_IN server;      
  23.     //收发缓冲区      
  24.     char szMessage[MSGSIZE];      
  25.     //成功接收字节的个数      
  26.     int ret;      
  27.                    
  28.     // Initialize Windows socket library      
  29.     WSAStartup(0x0202, &wsaData);      
  30.                    
  31.     // 创建客户端套节字      
  32.     sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //AF_INET指明使用TCP/IP协议族;      
  33.                                                          //SOCK_STREAM, IPPROTO_TCP具体指明使用TCP协议      
  34.     // 指明远程服务器的地址信息(端口号、IP地址等)      
  35.     memset(&server, 0, sizeof(SOCKADDR_IN)); //先将保存地址的server置为全0      
  36.     server.sin_family = PF_INET; //声明地址格式是TCP/IP地址格式      
  37.     server.sin_port = htons(PORT); //指明连接服务器的端口号,htons()用于 converts values between the host and network byte order      
  38.     server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); //指明连接服务器的IP地址      
  39.                                                         //结构SOCKADDR_IN的sin_addr字段用于保存IP地址,sin_addr字段也是一个结构体,sin_addr.s_addr用于最终保存IP地址      
  40.                                                         //inet_addr()用于将 形如的"127.0.0.1"字符串转换为IP地址格式      
  41.     //连到刚才指明的服务器上      
  42.     connect(sClient, (struct sockaddr *) &server, sizeof(SOCKADDR_IN)); //连接后可以用sClient来使用这个连接      
  43.                                                                         //server保存了远程服务器的地址信息      
  44.     while (TRUE) {      
  45.         printf("Send:");      
  46.         //从键盘输入      
  47.         gets(szMessage); //The gets() functionreads characters from stdin and loads them into szMessage      
  48.         // 发送数据      
  49.         send(sClient, szMessage, strlen(szMessage), 0); //sClient指明用哪个连接发送; szMessage指明待发送数据的保存地址 ;strlen(szMessage)指明数据长度      
  50.     }      
  51.                    
  52.     // 释放连接和进行结束工作      
  53.     closesocket(sClient);      
  54.     WSACleanup();      
  55.     return 0;      
  56. }  

 

测试图例:

C++局域网联机实战:用Winsock和Socket实现多人游戏通信(附完整代码) 本文详细介绍了如何使用C++、Winsock和Socket实现局域网多人游戏通信,包括核心架构、Socket配置、服务器与客户端实现及游戏状态同步优化。通过完整代码示例,帮助开发者快速掌握局域网联机游戏开发的关键技术。 阅读详情

相关推荐

跨平台tcp socket 客户端服务端(C++源码)

跨平台C++ tcp socket 客户端服务端源码 适用于linux window mac系统

C++学习之网络通信Socket技术

C++之网络通信socket学习

Significance的博客 5492

C语言设置和取得socket状态的相关函数用法

C语言setsockopt()函数:设置socket状态 头文件: #include <sys> #include <sys> 定义函数: int setsockopt(int s, int level, int optname, const void * optval, ,socklen_toptlen); 函数说明:setsockopt()用来设置参数s 所指定的socket 状态. 参数level 代表欲设置的网络层, 一般设成SOL_SOCKET 以存取socket 层. 参数optname 代表欲设置的选项, 有下列几种数值:    SO_

C++项目实战-socket编程

假设我们让发送数据的一端总是以大端字节序发送(对就是做一个统一的规定),那么接收数据的一端就知道我接受到的字节序总是大端字节序,如果接受方的字节序为小端,那么只需要大端数据装换成小端字节序就可以了。因此,Linux定义了下面这个新的通用的socket地址结构体,这个结构体不仅提供了足够大的空间用于存放地址值,而且是内存对齐的【内存对齐可以加快CPU访问速度,内存对齐问题见我的C语言专栏,有详细介绍】socket本意上“插座”的意思,在Linux环境中,用于表示进程间网络通信的特殊文件类型。...

weixin_46120107的博客 1万+

突破III-V/硅混合集成的挑战:UTC光电探测器能带工程仿真实践

本文探讨了UTC光电探测器在III-V/硅混合集成中的能带工程仿真实践,通过Ansys Lumerical平台实现多物理场仿真,解决晶格失配和能带不连续性等关键挑战。文章详细介绍了FDTD光学仿真和CHARGE电学仿真方法,优化器件性能,提升响应度和带宽,为高速光通信和量子计算提供技术支持。

weixin_29219539的博客 296

三边定位的最小二乘法运用

已知:条件基站到移动台的距离D,基站的坐标(xi,yi,zi) 求:移动台的坐标(x,y,z) 运用最小二乘法的核心是找到最小二乘法的矩阵形式即 Ax=B 在本次实验中通过三边定位计算得到 A=[A;2*(xi-x1),2*(yi-y1),2*(zi-z1]; %系数矩阵A b=[b;D1^2-Di^2+xi^2+yi^2+zi^2-x1^2-y1^2-z1^2]; %增广矩阵b

qq_26250141的博客 1万+

C++Socket通信总结(附C++实现)

一、Socket是什么    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 二、一些基本概念 TCP/IP            TCP/IP是个协

zhuyongxin_6688的博客 3万+

完整版:ultralytics下运行yoloworld并训练

本文介绍了Ultralytics YOLO环境的快速配置与使用流程:1) 通过conda创建Python 3.9环境并安装依赖包;2) 配置中科大镜像源加速安装PyTorch和Ultralytics;3) 准备YOLO格式数据集并修改data.yaml配置文件;4) 提供模型预测、训练和验证的常用指令,包括predict/train/val等命令参数设置。文章还包含CLIP模型下载、权重文件获取以及本地安装等注意事项,完整覆盖了从环境搭建到模型部署的全过程。

weixin_50209871的博客 1344

C++ Socket通信总结(附C++实现)

原文地址:http://blog.youkuaiyun.com/linghu_java/article/details/43488919 因为项目需要,服务端需要一个SOCKET来接收客户端的请求,好吧,没办法度娘哇,结果很多都是Linux的例子,功夫不负有心人啊,终于找到个demo,并且客户端代码详尽,记录之,以便以后查看。 一、Socket是什么    Socket是应用层与TCP/IP

AlphaGQ 1万+

Anolis 8系统下,手把手搞定Nginx、Redis、JDK8和Tomcat9的完整安装与配置(含开机自启)

本文详细介绍了在Anolis 8系统下搭建Java Web全栈环境的完整流程,包括JDK8、Tomcat9、Nginx和Redis的安装与配置,并实现系统级服务管理。通过深入每个组件的配置细节,揭示服务间的协同关系,最终打造一个生产级可用的标准化环境。

weixin_42556197的博客 159

win10+conda+pytorch-gpu安装

pytorch 官网上只有linux和Mac的程序包,没有windows系统的,但是windows系统还是可以用pytorch的。  github: https://github.com/peterjc123/pytorch-scripts 首先要安装anaconda: 推荐清华镜像 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ ...

一摩尔自由的博客 1万+

【转载】C++ Socket通信总结(附C++实现)

出处:【转】Socket通信总结(附C++实现) - 优快云博客 https://blog.youkuaiyun.com/e_wsq/article/details/12677667 文章目录 [隐藏] 一、Socket是什么 二、一些基本概念 三、java socket建立连接的过程 四、Socket 通信示例 五、建立通信链路 六、服务端代码: 七、客户端代码 ...

weixin_30670925的博客 141

Agent Skills应用解析:构建可扩展、高效率AI探员

Agent Skills是一个简洁而强大的概念:它是一个包含组织化的指令、脚本和资源的文件夹,智能体可以动态地发现并加载这些内容,以在特定任务中表现更佳。可组合性(Composability):一个Agent Skill是一个独立的、封装良好的能力单元。开发者可以为不同的功能(例如PDF处理、网络浏览、数据分析)创建独立的技能,然后根据需要将它们组合起来,赋能不同的智能体。这意味着不再需要为每个用例构建碎片化、定制设计的智能体,而是可以通过组合现有技能来快速构建新的专业智能体。

形上得其象,形下合于数;阴阳自济,玄理自明。 1627

基于Windows Socket的安全通信(C++实现,附源码)

原创作品,转载请注明出自xelz's blog 博客地址:http://mingcn.cnblogs.com/ 本文地址:http://mingcn.cnblogs.com/archive/2010/11/01/socket_c.html   被标题吸引到的大牛们原谅我吧,我只是菜鸟一只...   言归正传,还是那个课程设计,续昨天的AES加密(http://m

ybhjx的专栏 869

cadence中利用sva进行FPV实战(可直接使用)

在cadence中使用fpv进行formal验证

youzjuer的博客 749

基于STM32F4XX 、HAL库的GXHT30C温湿度传感器驱动应用C语言程序设计

define GXHT30C_STATUS_WRITE_CHK (1 << 0) // 写数据校验状态。#define GXHT30C_STATUS_HUMI_TRACK (1 << 11) // 湿度跟踪报警。#define GXHT30C_STATUS_TEMP_TRACK (1 << 10) // 温度跟踪报警。#define GXHT30C_STATUS_CMD_STATUS (1 << 1) // 命令执行状态。

PP_Cottage的博客 227

【C++】使用C++实现基于Socket的通信

Socket是一种网络通信接口,它提供了端到端的通信服务。Socket分为TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议)两种类型。TCP是面向连接的、可靠的、基于字节流的传输层通信协议,而UDP则是无连接的、不可靠的、基于数据报的传输层通信协议。// Type部分,通常使用16位整型// Length部分,也是16位整型// Value部分,使用字节向量存储。

kewaqi618的博客 3836

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【小沐学C++】C++实现socket网络通信

C++实现socket通信1、简介2、TCP方式2.1 服务端2.2 客户端后续 1、简介 socket顾名思义就是套接字的意思,用于描述地址和端口,是一个通信链的句柄。应用程序通过socket向网络发出请求或者回应。 socket编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW),前两者较常用。基于TCP的socket编程是流式套接字。 2、TCP方式 Server Initialize Winsock. Create a sock

爱看书的小沐 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: 使用c++builder调试代码时总是错过/忽略断点的解决方法
下一篇: SOCKET原理详解
hack_tian
博客等级 码龄16年 38粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值