自下而上分为 网络接口层、网络层、传输层、应用层四部分
其各层作用分为:
网络接口层:TCP/IP最底层,负责接收IP数据包并通过网络发送,或者从网络上接收物理帧,抽出IP数据报,交给IP层
网络层:是TCP/IP协议族中非常关键的一层,主要定义了IP地址格式,从而能够使得不同类型的数据再inernet上通畅地传输,IP协议就是一个网络层协议(IP数据包)
传输层:这一层的功能主要是提供应用程序间的通信,TCP/IP协议族在这一层的协议有TCP和udp。
应用层:TCP/IP协议族在这一层面有着很多协议来支持不同的应用,许多大家所熟悉的基于Internet的
应用的实现就离不开这些协议。如我们进行万维网(WWW)访问用到了HTTP协议、文件传输用FTP协议、电子邮件发送用SMTP、域名的解析用DNS协议、远程登录用Telnet协议等等,都是属于TCP/IP应用层的;就用户而言,看到的是由一个个软件所构筑的大多为图形化的操作界面,而实际后台运行的便是上述协议。(http、SMTP、telnet、DNS、tftp)
TCP的三次握手:
传输控制协议TCP简介
1:面向连接的、可靠的、基于字节流的传输层通信协议
2:将应用层的数据流分割成报文段并发送给目标节点的TCP层
3:数据包都有序号,对方收到则发送ACK确认,未收到则重传
4:使用校验和来校验数据在传输过程中是否有误
16位端口号:标示该段报文来自哪里(源端口)以及要传给哪个上层协议或应用程序(目的端口)。进行tcp通信时,一般client是通过系统自动选择的临时端口号,而服务器一般是使用知名服务端口号或者自己指定的端口号。
32位序号:表示一次tcp通信过程(从建立连接到断开)过程中某一次传输方向上的字节流的每个字节的编号。假定主机A和B进行tcp通信,A传送给B一个tcp报文段中,序号值被系统初始化为某一个随机值ISN,那么在该传输方向上(从A到B),后续的所有tcp报文断中的序号值都会被设定为ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025。
32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到对方的tcp报文段的序号值+1。假定主机A和B进行tcp通信,那么A发出的tcp报文段不但带有自己的序号,也包含了对B发送来的tcp报文段的确认号。反之也一样。
4位头部长度:表示tcp头部有多少个32bit字(4字节),因为4位最大值是15,所以最多有15个32bit,也就是60个字节是最大的tcp头部长度。
6位标志位:
URG:紧急指针是否有效(0:紧急指针无效1:紧急指针有效)
ACK:表示确认好是否有效,携带ack标志的报文段也称确认报文段(1:确认号有效0:确认号无效)
PSH:提示接收端应用程序应该立即从tcp接受缓冲区中读走数据,为后续接收的数据让出空间(尽快交给应用程序而不是在缓冲区域排队)
RST:表示要求对方重建连接。带RST标志的tcp报文段也叫复位报文段
SYN:表示建立一个连接,携带SYN的tcp报文段为同步报文段(syn 1 ack0 没有使用捎带的确认 11 为确认)
16位窗口大小:是TCP流量控制的一个手段,这里说的窗口是指接收通告窗口,它告诉对方本端的tcp接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。域)
FIN标志:表示告知对方本端要关闭连接了。(1发送方已经没有什么好发送得了,即关闭本方数据流)
16位校验和:由发送端填充,接收端对tcp报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意这个校验不仅包括tcp头部,也包括数据部分。这也是tcp可靠传输的一个重要保障。
16位紧急指针:是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此这个字段是紧急指针相对当前序号的偏移量。不妨称之为紧急偏移量,发送紧急数据时会用到这个。
握手是为了建立连接
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送SYN包(syn = j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户端的SYN(ack=j+1),同时自己也发送一个SYN包(syn = k),即 SYN+ACK包,此时服务期进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包向服务器发送确认包ACK(ack = k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手。
为什么需要三次握手才能建立起来连接?
为了初始化Sequence Number的初始值 (互相通知初始化的sequsence number)
首次握手隐患 ---SYN 超时问题
问题原因分析:
1:Server 端收到Client的SYN,回复SYN - ACK的时候未收到ACK确认
2:Server不断重试直到超时,Linux默认等待63s才断开连接
这时候服务器可能会遭受SYN Flood 攻击的风险,恶意攻击服务器,耗尽资源。
处理办法:
1:SYN队列满了之后,通过tcp_syncookies参数回发SYN Cookie
2:若为正常连接则Client会回发SYN Cookie,直至连接
建立链接之后客户端Client出现故障怎么办?
TCP 保活机制:
1:向对方发送保活探测报文,如果未收到响应则继续发送
2:尝试次数达到保活探测次数仍未收到响应则中断链接
TCP四次挥手。
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WALT_1状态:
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WALT状态;
第三次挥手:Server发送一个FIN,用来关闭Server到Client之间的数据传输,Server进入LAST_ACK状态;
第四次挥手:Client收到FIN后,Client进入TIME_WALT状态接着发送一个ACK给Server,确认序号为收到序号+1Server进入CLOSED状态,完成四次挥手
为什么会有TIME_WAIT状态?
1:确保有足够的时间让对方受到ACK包
2:避免新旧链接混淆
为甚么需要四次挥手才能断开链接?
1:因为双全工,发送方和接收都需要FIN报文和ACK报文
服务器出现大量CLOSE_WAIT的原因?
1:服务端一直在起头发送FIN报文,但是返回给客户端的信息是异常的没有发送ACK或者FIN报文确认,客户端一直都没有收到请求
1-1也就是说,对方关闭socket连接,我方忙于读或写,没有及时关闭连接
解决办法:
1:检查代码,特别是释放资源代码
2:检查配置,特别是处理请求的线程配置