• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

TCP/IP协议、网络IO编程BIO/NIO

武飞扬头像
Butterfly(Papillon)
帮助3

ISO网络模型与TCP/IP模型对比

学新通

TCP/IP协议族

IP网络协议是tcp/ip协议中非常重要的协议,它一般用来确定网络中唯一的一台计算设备。TCP协议是一个面向连接的可靠的协议,TCP通过三次握手建立连接和四次挥手关闭连接,通过带重传机制的肯定确认来确保数据的可靠性。UDP是不可靠的协议,数据发出去以后不管对端有没有接收到,可能会出现丢包的现象。

数据传输

学新通

为什么端口号有 65535 个?

因为在 TCP、UDP 协议报文的开头,会分别有 16 位二进制来存储源端口号和目标端口号,所以端口个数是 2^16=65536 个,但是 0 号端口用来表示所有端口,所以实际可用的端口号是 65535 个。

 一台主机上只能保持最多 65535 个 TCP 连接,对吗?

这个说法不对,确定TCP协议一个连接的元素包含:源IP地址,源IP端口,目标IP地址,目标IP端口。对于一台主机上的应用程序,不考虑机器的资源限制,可以建立200多万亿(2^32 * 2^16)个TCP连接。

TCP协议

tcp三次握手

学新通

第一次握手:客户端向服务端发起建立连接,发送SYN报文:SYN标志位置为1,seq_no (Sequence Number)填入一个随机数,客户端进入SYN_SEND状态。

第二次握手:服务端响应客户端发送ACK确认报文:SYN=1,ACK=1,ack等于第一次握手seq_no随机数加一,表示服务端已经收到第一次握手的请求,服务端也向客户端发送seq_no并赋值一个随机数。服务端进入SYN_RCVD状态

第三次握手:客户端收到服务端ACK确认报文,并向服务端发送一个确认报文:ACK=1,ack=seq_no 1,并进入连接的状态。服务端收到客户端的确认报文后也进入连接状态。

为什么需要三次握手?两次不可以吗?

首先两次肯定不行,因为TCP是面向连接的可靠协议。如果是两次,最后一次服务端没有收到来自客户端确认报文,服务端是不知道客户端是否收到自己发送给客户端的确认报文的,但是客户端收到服务端确认报文后就可以进入连接状态。最后只有客户端是可靠的,而服务端并不知道客户端进入连接状态。至于为什么不是四次,从第三次握手就可以看出双方都收到对端发送的确认报文了,不需要四次握手。

tcp漏洞SYN洪泛攻击

TCP发起连接中第二次握手时服务端是需要知道客户端的ip的,但此时连接还没有建立完成,所以服务端需要使用队列维持当前客户端IP的连接状态。那么洪泛攻击是指利用TCP建立连接中使用队列维护客户端IP状态进行伪造IP对服务端不停地发起连接,而伪造IP在真实中并不存在,所以服务端向这些伪造IP进行第二次握手时是找不到这些IP地址,也就是得不到第三次握手响应,那么队列会一直维持这些IP,直到队列撑满,拒绝连接。

如何预防SYN洪泛攻击呢?

延缓TCB分配:当服务端收到客户端第一次握手发起的请求后,服务端就会为这个请求分配一个TCB(传输控制块)资源,可以通过当连接建立以后再分配TCB

防火墙:防火墙确认对端是一个正常IP地址,也就是确认连接的有效后,才想服务端发起SYN请求

tcp四次挥手 

学新通

主动发起关闭方——client,被动关闭方——server

第一次挥手:client主动调用close(),发送FIN报文请求关闭连接。client将FIN标志位置位1并随机生成一个数赋值给seq_no,发送给server,表示数据发送完毕,进入FIN-WAIT-1状态

第二次挥手:server收到client关闭连接请求,会响应client发送确认关闭报文:ACK=1,ack=seq_no 1,同样生成一个随机数赋值给seq_no。此时server进入CLOSE-WAIT(等待关闭)状态,也就是进入半关闭状态,client进入FIN-WAIT-2状态。意味着client已经确定没有数据要发送给server端了,但是server若要发送数据给client端,client还可以接受数据。这种情况是存在的,在client将数据发送给server端后,server没有及时处理响应,此时client又发送FIN报文,server确认FIN报文后又将处理完的数据发送给client。

第三次挥手:server确定所有数据发送完毕以后,主动调用close()关闭套接字,向client发送FIN报文:FIN=1,ACK=1,seq_no=随机数,ack=第二次挥手中的ack。server进入LAST_ACK状态。

第四次挥手:client端收到server关闭连接请求后,向server发送确认关闭报文:ACK=1,ack=第三次挥手的seq_no 1,seq_no=第一次挥手的seq_no 1。此时client发送报文后进入TIME-WAIT状态,注意client端的TIME-WAIT时长为2 * MSL,也就是说client连接资源还没有释放。MSL为任何IP数据报文能够在因特网中存活的最长时间,任何TCP都需要给MSL选择一个值,建议2分钟,但是linux中为30s。也就是说在至少一分钟以后client释放TCB连接资源后彻底关闭连接进入CLOSED状态。server端收到确认报文后进入直接进入CLOSED状态。

为什么需要四次挥手?三次不行吗?

TCP是全双工的,必须保证两端进入CLOSED状态才真正关闭连接。也就是说发起关闭连接方都要收到对端的确认报文才关闭连接。但是在实际情况中是存在三次挥手就关闭连接的,server端(被动关闭方)在确认没有数据发送给client端后会将第二次和第三次挥手合并为一次发送给client端。 

为什么需要TIME-WAIT状态?

其一,确保server端收到client端第四次挥手的确认关闭连接报文。假设此时最后发送的确认关闭连接报文发送失败,服务端没有收到ACK报文,client需要在TIME-WAIT状态下重发ACK报文。

其二,TCP连接源端口是不可以重复的,当一个假设没有TIME-WAIT等待关闭状态,client发送ACK报文后直接进入关闭状态释放端口资源了,此时应用程序建立一个连接与刚关闭的连接类似,也就是同一个源端口号,新的连接有可能收到原来关闭连接的迟来报文段,这显然是不合理的。

TCP Wireshark和tcpdump抓包实战

Wireshark

主机mysql客户端发起对虚拟机192.168.43.12的mysql服务连接,使用wireshark监听虚拟的网卡抓取网络报文

学新通 

从wireshark抓取的网络包里找到TCP三次握手创建连接的过程:

学新通

学新通

学新通

学新通

学新通

TCP四次挥手

学新通

tcpdump

 建立连接三次握手

学新通

学新通

关闭连接四次挥手

学新通学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhffek
系列文章
更多 icon
同类精品
更多 icon
继续加载