1 POSIX介绍
POSIX(Portable Operating System Interface)API是一组操作系统接口标准,旨在为不同的Unix操作系统提供一致的编程界面。它包括了许多常见的操作系统服务,如进程管理、文件管理、网络通信等。POSIX API由IEEE制定和管理,其标准编号为IEEE 1003。许多现代的操作系统都支持POSIX API,包括Linux、Mac OS X和Solaris等。从Windows 10版本开始,Microsoft已经将POSIX子系统(Subsystem for UNIX-based Applications,SUA)添加到Windows操作系统中,该子系统支持运行基于UNIX的应用程序,并提供了POSIX API的实现。
网络这一块主要用到以下8个api
1 socket
2 bind
3 listen
4 accept
5 connect
6 recv
7 send
8 close
2 网络协议栈中的一些概念
TCB
TCB是“Transmission Control Block”的缩写,是网络通信中的一种数据结构。它是用来维护TCP协议中的连接状态信息的,可以保存已建立连接的IP地址、端口号、序列号、确认号等关键信息。在TCP协议中,每个数据包都会带有一个TCB,用来标识该数据包属于哪个连接,并记录接收和发送方的状态信息。同时,TCB也用于管理TCP连接的流量控制和拥塞控制等功能。因此,TCB在TCP协议中扮演着非常重要的角色
TCB包含以下信息:
1.本端IP地址和端口号 sport
2.对端IP地址和端口号 dport
3.TCP状态(如SYN_SENT、SYN_RECEIVED、ESTABLISHED、FIN_WAIT_1等)
4.发送窗口大小、接收窗口大小
5.序列号、确认号
6.最后一次发送或接收数据的时间戳
7.计时器(如重传计时器、保活计时器等)
8.缓冲区指针等。
当TCP连接建立时,这些参数被初始化并存储在TCB中。随着数据的发送和接收,这些参数会被动态地修改和更新。例如,每次发送数据时,序列号会增加;每次接收数据时,确认号会更新。
通过TCB,TCP实现了可靠的数据传输、拥塞控制和流量控制等功能。
五元组
五元组是网络数据传输中的五个关键参数,包括:源IP地址(Source IP Address)、目标IP地址(Destination IP Address)、源端口号(Source Port)、目标端口号(Destination Port)和协议类型(Protocol),这里简写为:五元组(sip dip sport dport proto)
通过TCP可以查找到五元组,反过来也行
问:端口只有65535个,怎么做到百万级连接?
TCB的唯一性就是五元组,只要五元组不冲突,就可以建立唯一的链接
那么理论上可建立的连接的总数将是:n_sip x n_dip x n_sport x n_dport x n_proto
实际操作起来,受硬件,网络等因素影响,需要精心设计,与测试。
tcp状态迁移图
参见: https://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&dyTabStr=MCw1LDEsNiw0LDMsNyw4LDIsOQ%3D%3D&word=tcp%E7%8A%B6%E6%80%81%E8%BF%81%E7%A7%BB%E5%9B%BE
结合tcp状态迁移图 理解 Posix API
1 bind是如何实现的呢?
socket--> 插座,fd--> tcb 两个部分组成
bind: 把fd 与 tcp绑定,即把(ip, port)绑定在一起,如果不绑定,发送的端口就不确定
连接建立好后,就不分服务器与客户端,进入平等状态,就是建立了连接
2 send返回正数的意义
仅代表数据copy到了内核,进入了tcb, 什么时候发,分几次发,是协议栈决定的
mtu,最大传输端元,ifconfig就可以看到
mtu对send的大小没有限制
tcp头里面是不带长度的
我发5K,对方怎么知道我收到了5K?()
tcp发完后,它能保证顺序 (我先发3k,再发2k与一次性发5k没有区别)
应用层怎么区分呢?加 分包,分隔符
send真正发送成功是: 对方回复应用层的确认值ack,才能确认收到
为什么要确认呢?是因为存在弱网的环境,比如进高铁,进隧道,电梯,需要通过应用层确认。
弱网环境下:tcb的ack不一定能够收得到, 也不一定回了ack
acknum seqnum 这连个值是在tcp头里面,单位是 字节数
我方发的seq 减去 对方回的ack 的差,是我方还没有发送成功的字节数 ===> 为什么tcp头里面不带长度字段
3 close 链接断开
fin (final)
fin 一般是和其他包在一起的,(抓fin包的时候要注意一些)
可以使用netstat命令来查看当前系统中的close wait连接数量。在命令行中输入"netstat -n | grep CLOSE_WAIT | wc -l",即可显示当前系统中的close wait连接数量。如果该数字较高,则说明系统中存在大量的close wait连接。
大量close wait的段状态,是什么原因造成的?
=> 没有及时调用close, 异步分离调用close
大量的client关掉==>雪崩
双方同时调用close,(就变成了三次挥手了),进入closing状态
双方进入time_wait状态
sysctl可以设置time_wait time_wait2的超时,然后强行退出
文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:链接