什么是TCP?
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。
* 面向连接:一定是[一对一]才能连接,不能像UDP协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;
* 可靠的:无论网络链路中出现了怎样的链路变化,TCP都可以保证一个报文一定能够到达接收端
*
字节流:用户消息通过TCP协议传输时,消息可能会被操作系统[分组]成多个TCP报文,如果接收端不知道消息的边界,是无法读出一个有效的用户消息的。并且TCP报文是[有序的],当前一个TCP报文没有收到的时候,即使它先收到了后面的TCP报文,那么也不能扔给应用层去处理,同时对[重复]的TCP报文会自动丢弃。
TCP头格式
序列号:在建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机,每发送一次数据,就累加一次该数据字节数的大小。用来解决网络包乱序的问题。
确认应答号:指下一次期望收到的数据的序列号,发送端收到这个确认应答后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题
控制位:
* ACK:该位为1时,确认应答的字段变为有效,TCP规定除了最初建立连接时的SYN包之外该位必须设置为1.
* RST:该位为1时,表示TCP连接中出现异常必须强制断开连接。
* SYN:该位为1时,表示希望建立连接,并在其序列号的字段进行序列号初始值的设定
* FIN:该位为1时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以互相交换FIN位为1的TCP段。
为什么需要TCP,TCP工作在哪一层?
IP层是[不可靠]的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。
如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的TCP协议来负责。
因为TCP是一个工作在传输层的可靠数据传输的服务,它能确保接收的网络包时无损坏、无间隔、非冗余和按序的。
TCP连接
1. 什么是TCP连接?
简单来说就是,用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
所以,建立一个TCP连接时需要客户端与服务端达成上述三个信息的共识。
* Socket:由ip地址和端口号组成
* 序列号:用来解决乱序问题
* 窗口大小:用来做流量控制
2. 如何确定一个TCP连接?
TCP四元组可以唯一地确定一个连接,四元组包括:
源地址和目标地址的字段(32位)是在IP头部中,作用是通过IP协议发送报文给对方主机。
源端口和目标端口的字段(16位)是在TCP头部中,作用是告诉TCP协议应该把报文发送给哪个进程
有一个IP的服务端监听了一个端口,它的TCP最大连接数是多少?
理论计算公式:最大TCP连接数 = 客户端IP数 X 客户端的端口数
对于IPV4,客户端IP数量最多为2的32次方,客户端的端口数量最多为2的16次方,也就是服务端单机最大TCP连接数约为2的48次方(
目标地址与目标端口共48位)
当然,服务器最大并发TCP连接远不能达到理论上限,会受以下因素影响:
* 文件描述符限制:每一个TCP连接都是一个文件,如果文件描述符被占满了,就会发生Too many open
files.linux可对打开的文件描述符的数量分别做了三个方面的限制:
* 系统级:当前系统可打开的最大数量,通过cat /proc/sys/fs/file-max查看;
* 用户级:指定用户可打开的最大数量,通过cat /etc/security/limits.conf查看;
* 进程级:单个进程可打开的最大数量,通过cat /proc/sys/fs/nr_open查看;
* 内存限制,每个TCP连接都要占用一定内存,操作系统的内存是有限的,如果内存资源被占满后,会发生OOM。