TCP 和 UDP 的 Socket 调用

2023-09-13 21:45:10

在网络层,Socket 函数需要指定到底是 IPv4 还是 IPv6,分别对应设置为 AF_INET 和 AF_INET6。另外,还要指定到底是 TCP 还是 UDP。TCP 协议是基于数据流的,所以设置为 SOCK_STREAM,而 UDP 是基于数据报的,因而设置为 SOCK_DGRAM。

TCP 的服务端要先监听一个端口,一般是先调用 bind 函数,给这个 Socket 赋予一个 IP 地址和端口。为什么需要端口呢?要知道,你写的是一个应用程序,当一个网络包来的时候,内核要通过 TCP 头里面的这个端口,来找到你这个应用程序,把包给你。为什么要 IP 地址呢?有时候,一台机器会有多个网卡,也就会有多个 IP 地址,你可以选择监听所有的网卡,也可以选择监听一个网卡,这样,只有发给这个网卡的包,才会给你。

当服务端有了 IP 和端口号,就可以调用 listen 函数进行监听。在 TCP 的状态图里面,有一个 listen 状态,当调用这个函数之后,服务端就进入了这个状态,这个时候客户端就可以发起连接了。

在内核中,为每个 Socket 维护两个队列。一个是已经建立了连接的队列,这时候连接三次握手已经完毕,处于 established 状态;一个是还没有完全建立连接的队列,这个时候三次握手还没完成,处于 syn_rcvd 的状态。

接下来,服务端调用 accept 函数,拿出一个已经完成的连接进行处理。如果还没有完成,就要等着。

在服务端等待的时候,客户端可以通过 connect 函数发起连接。先在参数中指明要连接的 IP 地址和端口号,然后开始发起三次握手。内核会给客户端分配一个临时的端口。一旦握手成功,服务端的 accept 就会返回另一个 Socket。

监听的 Socket 和真正用来传数据的 Socket 是两个,一个叫作监听 Socket,一个叫作已连接 Socket

连接建立成功之后,双方开始通过 read 和 write 函数来读写数据,就像往一个文件流里面写东西一样。

基于 TCP 协议的 Socket 程序函数调用过程。

说 TCP 的 Socket 就是一个文件流,是非常准确的。因为,Socket 在 Linux 中就是以文件的形式存在的。除此之外,还存在文件描述符。写入和读出,也是通过文件描述符。

在内核中,Socket 是一个文件,那对应就有文件描述符。每一个进程都有一个数据结构 task_struct,里面指向一个文件描述符数组,来列出这个进程打开的所有文件的文件描述符。文件描述符是一个整数,是这个数组的下标。

UDP 是没有连接的,所以不需要三次握手,也就不需要调用 listen 和 connect,但是,UDP 的交互仍然需要 IP 和端口号,因而也需要 bind。UDP 是没有维护连接状态的,因而不需要每对连接建立一组 Socket,而是只要有一个 Socket,就能够和多个客户端通信。也正是因为没有连接状态,每次通信的时候,都调用 sendto 和 recvfrom,都可以传入 IP 地址和端口。

最大 TCP 连接数 = 客户端 IP 数×客户端端口数。对 IPv4,客户端的 IP 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。

当然,服务端最大并发 TCP 连接数远不能达到理论上限。首先主要是文件描述符限制,按照上面的原理,Socket 都是文件,所以首先要通过 ulimit 配置文件描述符的数目;另一个限制是内存,按上面的数据结构,每个 TCP 连接都要占用一定内存,操作系统是有限的。

1、多进程方式

这就相当于你是一个代理,在那里监听来的请求。一旦建立了一个连接,就会有一个已连接 Socket,这时候你可以创建一个子进程,然后将基于已连接 Socket 的交互交给这个新的子进程来做。

2、多线程方式

在 Linux 下,通过 pthread_create 创建一个线程,也是调用 do_fork。不同的是,虽然新的线程在 task 列表会新创建一项,但是很多资源,例如文件描述符列表、进程空间,还是共享的,只不过多了一个引用而已。

有个 C10K,它的意思是一台机器要维护 1 万个连接,就要创建 1 万个进程或者线程,那么操作系统是无法承受的。如果维持 1 亿用户在线需要 10 万台服务器,成本也太高了。

3、IO 多路复用,一个线程维护多个 Socket

由于 Socket 是文件描述符,因而某个线程盯的所有的 Socket,都放在一个文件描述符集合 fd_set 中,这就是项目进度墙,然后调用 select 函数来监听文件描述符集合是否有变化。一旦有变化,就会依次查看每个文件描述符。

4、IO 多路复用,从“派人盯着”到“有事通知”

能完成这件事情的函数叫 epoll,它在内核中的实现不是通过轮询的方式,而是通过注册 callback 函数的方式,当某个文件描述符发送变化的时候,就会主动通知。

这种通知方式使得监听的 Socket 数据增加的时候,效率不会大幅度降低,能够同时监听的 Socket 的数目也非常的多了。上限就为系统定义的、进程打开的最大文件描述符个数。因而,epoll 被称为解决 C10K 问题的利器。

此文章为9月Day13学习笔记,内容来源于极客时间《趣谈网络协议》,推荐该课程。

更多推荐

DNG格式详解,DNG是什么?为何DNG可以取代RAW统一单反相机、苹果安卓移动端相机拍摄输出原始图像数据标准

返回图像处理总目录:《JavaCV图像处理合集总目录》前言在DNG格式发布之前,我们先了解一下之前单反相机、苹果和安卓移动端相机拍照输出未经处理的原始图像格式是什么?RAW什么是RAW?RAW是未经处理、也未经压缩的格式。可以把RAW概念化为“原始图像编码数据”或更形象的称为“数字底片”。RAW是CMOS或者CCD图像

设计模式-原型模式

相信很多同学小时候都玩过《超级马里奥》这款游戏,不知道你是否还记得你曾经营救过的公主?你们在一起了吗?哈哈!小时候我家可没这个条件,经常跑到同学家里玩(或者看别人玩),可羡慕死我了。小的时候只知道玩,长大后才知道原来这么多关卡的马里奥竟然只占用40KB,我现在随手拍张照片也有个5MB左右呀!后来经过查阅资料才知道其中的

SpringBoot中级开发--事务配置管理(10)

事务在整个开发框架中是一个非常常用的功能,特别涉及到数据库操作。像Mysql,就有4个数据库级别:(1)READUNCOMMITTED(读未提交):允许读取未提交的数据。这种级别的事务可以读取到其他事务未提交的数据,可能会导致脏读、不可重复读和幻读等问题。(2)READCOMMITTED(读已提交):只能读取已经提交的

接口测试工具详解

首先,什么是接口呢?接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的,比如说咱们用的app、网址这些它在进行

c#设计模式-创建型模式 之 建造者模式

简介:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。提供了一种创建对象的最佳方式。一个Builder类会一步一步构造最终的对象。该Builder类是独立于其他对象的。意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。建造者模式的核心思想就是将一个复杂对象的构建与其表示分

二,手机硬件参数介绍和校验算法

系列文章目录第一章安卓aosp源码编译环境搭建第二章手机硬件参数介绍和校验算法第三章修改安卓aosp代码更改硬件参数第四章编译定制rom并刷机实现硬改(一)第五章编译定制rom并刷机实现硬改(二)第六章不root不magisk不xposedlsposedfrida原生修改定位第七章安卓手机环境检测软件分享第八章硬改之设

【C语言】指针的进阶(一)

目录前言1.字符指针2.指针数组3.数组指针3.1数组指针的定义3.2&数组名VS数组名3.3数组指针的使用4.数组参数、指针参数4.1一维数组传参4.2二维数组传参4.3一级指针传参4.4二级指针传参5.函数指针前言指针在C语言中可谓是有着举足轻重的存在,初学C语言的我们在《指针》章节已经接触过了一些指针的知识,知道

【网络豆送书第四期】《用户画像:平台构建与业务实践》

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。公众号:网络豆座右铭:低头赶路,敬事如仪个人主页:网络豆的主页​​​​​本期好书推荐:《用户画像:平台构建与业务实践》粉丝福利:书籍赠送:共计送出4本参与方式:关注公众号:网络豆云计算学堂回复关键词:第四期送书截止时间:2023年9月24日中午12:00

嵌入式C语言知识复习和提高

文章目录前言基础知识main函数防BUG注释(重要)关键字标识符命名(驼峰命名)常量类型变量printf1.输出不同类型数据2.输出不同宽度数据3.不同类型数据长度归类scanf函数运算符sizeof(运算符,优先级2)逗号运算符关系运算符逻辑运算符三目运算符强制类型转换流程控制if语句switchcase循环结构fo

Python基于Flask的高校舆情分析,舆情监控可视化系统

目录一、数据采集二、数据预处理三、舆情分析四、数据可视化五、系统集成六、用户交互功能实现:七、系统优化总结随着互联网的普及和信息量的爆炸式增长,网络舆情数据变得越来越庞大和复杂。高校作为社会的重要组成部分,其舆情数据同样具有重要意义。因此,为了更好地监控和了解高校舆情数据的动态和发展趋势,我们需要构建一个基于Flask

Linux 终端命令总结

一、常用的七条命令命令对应英文作用lslist查看当前文件夹下的内容pwdprintworkdirectory查看当前所在文件夹cd[目录名]changedirectory切换文件夹touch[文件名]touch如果文件不存在新建文件mkdir[目录名]makedirectory创建目录rm[文件名]remove删除指

热文推荐