在linux下socket是用一个文件描述符来表示,对于linux来说从某个socket读数据和从某个文件读数据是一样的;linux下文件描述符的范围是1024,也就是每个用户进行所能使用的最大的文件描述符的数量不能超过此值,但是这个值可以进行修改,在服务器程序中,该值可以修改为10w、20w甚至更大的值。

socket可以用一个五元组来标识:<源地址,源端口,目的地址,目的端口,使用的协议>
例如:地址为A的主机欲用tcp协议从端口3256向地址为B的主机的5432端口发送消息,那用一个socket来表示上述数据传输就是:
<A,3256,B,5432,tcp>
      对于socket来说,五元组中的任何一个元素发生变化都表示一个新的socket。这5个元素分为三类:地址、端口和协议。其中:
      地址:
      一般都是指ip地址,例如常用的IPV4的ip地址形式为:210.45.0.12;一个地址就标识了一台主机,如果在通信程序中知道了对方的地址,你就知道往哪台机子上发送了。但是现在还不知道发给那台机子上的哪个程序。
      端口:
      端口的数据类型是unsigned short,为16位,因此端口的使用范围为0~65535,其中0~1024之间的端口为特殊用途,用户可以使用的端口范围需在1024~65535之间,端口标识了一个服务或者是应用程序。
      因此知道了一个地址+端口,就知道了向哪台机子的哪个程序发送数据。但是,现在还不知道跟对方通信是采用哪种协议,就像两个人要说话,但是还不知道该用英文说还是中文说。
      协议:

协议是指通信双方使用的通信协议,例如tcp、udp之类。协议就表明了双方采用什么方式进行通信。

因此,知道:地址+端口+协议,就知道了向哪个机子的哪个程序使用哪个协议进行通信。

      为什么使用客户端测试服务器时,一台客户端主机的socket连接只能到6万多个,而服务器却可以接受10w、20万的连接(这里所说的连接就是socket)

例如:

使用一台服务器S和3个测试客户端C1、C2、C3进行测试,具体情况为:
服务器程序S运行的主机地址为:192.168.4.220,监听端口为1883。
测试客户端程序C1运行的主机地址为:192.168.4.221
测试客户端程序C2运行的主机地址为:192.168.4.222
测试客户端程序C3运行的主机地址为:192.168.4.223
此时在测试客户端程序C1、C2、C3中一直创建新连接到服务器程序S,但是每个机子的测试客户端连接数只能到6w多个,这个跟机子的情况有关,有的可以连到6.4万,有的更少;而此时服务器却支持了近20W个连接。

服务器程序S运行的主机地址为:192.168.4.220,监听端口为1883。
测试客户端程序C1运行的主机地址为:192.168.4.221
测试客户端程序C2运行的主机地址为:192.168.4.222
测试客户端程序C3运行的主机地址为:192.168.4.223
此时在测试客户端程序C1、C2、C3中一直创建新连接到服务器程序S,但是每个机子的测试客户端连接数只能到6w多个,这个跟机子的情况有关,有的可以连到6.4万,有的更少;而此时服务器却支持了近20W个连接。

答案是:
对于server:
      根据前面的描述,server将会为这三台测试机中的每个连接都创建一个socket进行通信,每个socket就是一个五元组:
      server程序中为C1建立的socket连接为(1025~1078之间的端口被其他程序占用了):
第一组
<192.168.4.221, 1078, 192.168.4.220, 1883>
<192.168.4.221, 1079, 192.168.4.220, 1883>
......
<192.168.4.221, 65535, 192.168.4.220, 1883>

server程序中为C2建立的socket连接为(1025~1973)之间的端口被其他程序占用了):
第二组
<192.168.4.222, 1973, 192.168.4.220, 1883>
<192.168.4.222, 1974, 192.168.4.220, 1883>
......
<192.168.4.222, 65535, 192.168.4.220, 1883>

server程序中为C3建立的socket连接为(1025~1623)之间的端口被其他程序占用了):
第三组
<192.168.4.223, 1623, 192.168.4.220, 1883>
<192.168.4.223, 1624, 192.168.4.220, 1883>
......
<192.168.4.223, 65535, 192.168.4.220, 1883>

上述socket所对应的五元组中,每一组内部的五元组中,都是端口发生了变化,但是其他元素:源地址、目的地址、目的端口、协议都没有变化;

这三组之间进行对比时,则变化的是源地址,其他元素:源端口、目的地址、目的端口、协议都没有变化(源端口可能不会全部重合,但是大部分都是一样的);

由于五元组中任何一个成员发生了变化,也就是对应了一个全新的socket。
在server中,只需要为每个五元组socket产生一个文件描述符来标识进行区分即可,此时只要将所在机子的文件描述符限制值改大,只要超过20W,就可以让其支持这么多的socket连接了,

对于测试客户端:
以第一组为例:
      其产生的socket所对应的五元组为:
<192.168.4.221, 1078, 192.168.4.220, 1883>
<192.168.4.221, 1079, 192.168.4.220, 1883>
......
<192.168.4.221, 65535, 192.168.4.220, 1883>
      可以看到源地址、目的地址、目的端口、协议这4项是固定的,没有办法改变,所以它此时只能变化一个元素:源端口号!
      由于linux操作系统中port的范围有限,只能用1024~65535之间的,如果这之间的端口号再被别的程序占用一些,能用的就更少了,因此它只能支持6w左右的连接。

关于socket的一些总结相关推荐

  1. linux常用c函数(中文版)

    都是linux的c函数东西略多,用页面搜索来查找吧. << Back to man.ChinaUnix.net isalnum(测试字符是否为英文或数字) 相关函数 isalpha,isd ...

  2. 百度前200页部分答案(初稿)

    1操作系统中 heap 和 stack 的区别 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. 在函数中定义的一些基本类 ...

  3. RPC 笔记(08)— socket 通信(多进程多线程服务器)

    在上一节中如果并行的客户端连接数超过了默认开启进程的数量,那么后来的客户端请求将会阻塞,为了不阻塞新的客户端,我们可以将进程的单线程改成多线程即可. ​ 服务端代码: import json impo ...

  4. RPC 笔记(07)— socket 通信(多进程服务器)

    上节我们完成了一个简单的多线程服务器,可以并发处理多个客户端连接.但是 Python 由于全局解释器锁 GIL 的存在,致使多个线程只能占满一个 CPU 核心,多线程并不能充分利用多核的优势.所以多数 ...

  5. RPC 笔记(06)— socket 通信(多线程服务器)

    1. 客户端代码 import json import time import struct import socketdef send_request(sock_obj, method, param ...

  6. RPC 笔记(05)— socket 通信(单线程服务器)

    1. Python 标准库 1.1 socket 提供 RPC 服务的网络通信功能,方便用户编写 tcp/udp 相关的代码.两个不同机器的进程需要通信时,可以通过 socket 来传输数据. ​ 客 ...

  7. Docker使用遇到问题Got permission denied while trying to connect to the Docker daemon socket解决方案

    Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker. ...

  8. python 网络编程之Socket通信案例消息发送与接收

    背景 网络编程是python编程中的一项基本技术.本文将实现一个简单的Socket通信案例消息发送与接收 正文 在python中的socket编程的大致流程图如上所示 我们来首先编写客户端的代码: # ...

  9. Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2)

    安装了mysql, 使用命令mysql -u root -p 弹出Can 't connect to local MySQL server through socket '/tmp/mysql.soc ...

  10. C# Socket系列三 socket通信的封包和拆包

    通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! 1 class Program 2 { 3 static void Mai ...

最新文章

  1. ios开发学习--cocos2d(cocos2d)效果源码分享--系列教程
  2. 学ASP只需一小时!
  3. Java Compiler disable()方法与示例
  4. The table(CF-226D)
  5. About Me Leo是谁
  6. 【CodeVS2226】飞行棋
  7. pandas rolling方法_【干货】pandas相关工具包
  8. Share Favorites
  9. 马云生气了 mysql_“马云生气了”之增删改查
  10. 【node】node连接mongodb操作数据库
  11. Opencv 移植 (亲测有效)
  12. 少有人走的路 读书笔记
  13. 共享计算机突然无法访问,共享的文件突然不能访问了电脑重启后又能访问为什么...
  14. 电脑通信端口带感叹号,WIN7设备管理器里面的端口前面有个黄色感叹号怎么解决?...
  15. React 语法之let和const命令
  16. 网格简化技术研究报告
  17. ORB-SLAM3编译问题 recipe for target ‘CMakeFiles/ORB_SLAM3.dir/src/LocalMapping.cc.o‘ failed
  18. 基于决策树的交通拥堵成因分析
  19. 有没有英语语音测试软件,推荐我用过的几款真正可以找外国人练口语的软件app...
  20. maven修改为阿里巴巴的仓库地址

热门文章

  1. k8s查看pod的yaml文件_每天5分钟|轻松掌握开发工作中必会的k8s-yaml配置说明和常用命令...
  2. Navicat连接mysql8.0.1版本出现1251--Client does not support authentication protocol requested by server的解决
  3. 如何设置EditPlus保存时不生成bak文件
  4. day22 java的枚举
  5. 组合体视图的画图步骤_(完整版)组合体视图画法教案
  6. ideal如何快速导入import_【MAC版】pr预设安装目录?pr如何快速批量导入lut
  7. c++ 协程_Python3 协程(coroutine)介绍
  8. html li去掉黑点_10分钟教你Python爬虫(上) HTML和爬虫基础
  9. java 返回第k小的数_java – 给定n和k,返回第k个置换序列
  10. unity 中文_Unity无情大爆料时间Unity3D的脚本语言