zoukankan      html  css  js  c++  java
  • [基础] TCP小结

    抓包示例

    root@python:~# tcpdump -n -S  tcp port 5009 # -S 参数的目的是获得ack的绝对值,不加该参数,第三次握手的ack为相对值1
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    17:35:43.707223 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [S], seq 267775201, win 8192, options [mss 1452,nop,wscale 2,nop,nop,sackOK], length 0   # **客户端发起请求,第一次握手**
    17:35:43.707299 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [S.], seq 3046340720, ack 267775202, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    17:35:43.729057 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [.], ack 3046340721, win 16698, length 0 # **三次握手结束**
    17:35:43.778243 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [P.], seq 267775202:267775428, ack 3046340721, win 16698, length 226 # **开始传送数据**
    17:35:43.778299 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], ack 267775428, win 237, length 0
    17:35:43.780225 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], seq 3046340721:3046343625, ack 267775428, win 237, length 2904
    17:35:43.780254 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [P.], seq 3046343625:3046343827, ack 267775428, win 237, length 202
    17:35:43.802585 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [.], ack 3046343827, win 16698, length 0
    17:35:43.803603 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [P.], seq 267775428:267775619, ack 3046343827, win 16698, length 191
    17:35:43.803988 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [P.], seq 3046343827:3046343878, ack 267775619, win 245, length 51
    17:35:43.825824 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [P.], seq 267775619:267775895, ack 3046343878, win 16685, length 276
    17:35:43.865696 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], ack 267775895, win 254, length 0
    17:35:44.314454 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], seq 3046343878:3046346782, ack 267775895, win 254, length 2904
    17:35:44.314472 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], seq 3046346782:3046349686, ack 267775895, win 254, length 2904
    17:35:44.314477 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], seq 3046349686:3046352590, ack 267775895, win 254, length 2904
    17:35:44.314482 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [P.], seq 3046352590:3046352839, ack 267775895, win 254, length 249
    17:35:44.336458 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [.], ack 3046352839, win 16698, length 0
    17:35:44.402718 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [P.], seq 267775895:267775926, ack 3046352839, win 16698, length 31
    17:35:44.402758 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], ack 267775926, win 254, length 0
    17:35:44.402869 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [F.], seq 3046352839, ack 267775926, win 254, length 0   # **四次挥手开始**
    17:35:44.404033 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [F.], seq 267775926, ack 3046352839, win 16698, length 0
    17:35:44.404047 IP 172.16.10.164.5009 > 122.235.85.89.49302: Flags [.], ack 267775927, win 254, length 0
    17:35:44.424589 IP 122.235.85.89.49302 > 172.16.10.164.5009: Flags [.], ack 3046352840, win 16698, length 0 # **四次挥手结束**
    

    Flags包标志:

    S=SYN       发起连接标志。
    P=PUSH      传送数据标志。
    F=FIN       关闭连接标志。
    ACK         表示确认包。
    RST=RESET   异常关闭连接。
    .           表示没有任何标志。
    

    tcp示意图
    tcp状态转换图

    TCP连接建立(三次握手)

    客户端A,服务器B,初始序号seq,确认号ack
    
    初始状态:B处于监听状态,A处于打开状态
    
    A -> B : seq = x (A向B发送连接请求报文段,A进入同步发送状态SYN-SENT)
    
    B -> A : ack = x + 1,seq = y (B收到报文段,向A发送确认,B进入同步收到状态SYN-RCVD)
    
    A -> B : ack = y+1 (A收到B的确认后,再次确认,A进入连接状态ESTABLISHED)
    
    连接后的状态:B收到A的确认后,进入连接状态ESTABLISHED
    

    TCP连接释放(四次挥手)

    A -> B : seq = u (A发出连接释放报文段,进入终止等待1状态FIN-WAIT-1)
    
    B -> A : ack = u + 1,seq = v (B收到报文段,发出确认,TCP处于半关闭,B还可向A发数据,B进入关闭等待状态WAIT)
    
    B -> A : ack = u + 1,seq = w (B重复发送确认号,进入最后确认状态LAST-ACK)
    
    A -> B : ack = w + 1,seq = u + 1 (A发出确认,进入时间等待状态TIME-WAIT)
    
    经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态
    

    为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

    三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。
    这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,
    仅仅表示对方不再发送数据了但是还能接收数据,我们也未必全部数据都发送给对方了,所以我们不可以立即close,也可以发送一些数据给对方后,
    再发送FIN报文给对方来表示同意现在关闭连接,因此,我们的ACK和FIN一般都会分开发送。

    TCP可靠传输的实现

    TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。TCP 的可靠传输机制用字节的序号进行控制。TCP 所有的确认都是基于序号而不是基于报文段。
    发送过的数据未收到确认之前必须保留,以便超时重传时使用。发送窗口没收到确认不动,和收到新的确认后前移。

    发送缓存用来暂时存放: 发送应用程序传送给发送方 TCP 准备发送的数据;TCP 已发送出但尚未收到确认的数据。
    接收缓存用来暂时存放:按序到达的、但尚未被接收应用程序读取的数据; 不按序到达的数据。

    RST标记

    RST表示连接重置,用于关闭那些已经没有必要继续存在的连接。一般情况下表示异常关闭连接,区别与四次分手正常关闭连接。

    产生RST的三个条件是:

    1. 目的地为某端口的SYN到达,然而在该端口上并没有正在监听的服务器;
    2. TCP想取消一个已有连接;
    3. TCP接收到一个根本不存在的连接上的分节;

    几种场景:

    1. 端口未打开,客户端向服务端某端口发起连接请求SYN,但是目的服务端主机不存在该端口,此时向客户端回应RST,中断连接请求。
    2. 请求超时,常见的有 tw_bucket 满了、tcp 连接队列爆满且开启 tcp_abort_on_overflow、配置 so_linger、关闭未清空读缓冲区的连接。
    3. 提前关闭,TCP应用程序接收数据是从操作系统中接收的TCP数据,如果数据到达了操作系统但是我应用数据不想继续接收数据了,此时RST中断连接。
    4. 在一个已关闭的socket上收到数据,显然是异常的,此时应RST中断连接。

    配置与坑

    大多都写开启net.ipv4.tcp_tw_recycle这个开关,可以快速回收处于TIME_WAIT状态的socket(针对Server端而言)。
    而实际上,这个开关,需要net.ipv4.tcp_timestamps(默认开启)这个开关开启才有效果。
    更被提到却很重要的一个信息是:当tcp_tw_recycle开启时(tcp_timestamps同时开启,快速回收socket的效果达到),对于位于NAT设备后面的Client来说,
    是一场灾难——会导到NAT设备后面的Client连接Server不稳定(有的Client能连接server,有的Client不能连接server)。
    也就是说,tcp_tw_recycle这个功能,是为“内部网络”(网络环境自己可控——不存在NAT的情况)设计的,对于公网不宜使用。

    拓展阅读

  • 相关阅读:
    MOSS中的User的Title, LoginName, DisplayName, SID之间的关系
    如何在Network Monitor中高亮间隔时间过长的帧?
    SharePoint服务器如果需要安装杀毒软件, 需要注意什么?
    如何查看SQL Profiler? 如何查看SQL死锁?
    什么是Telnet
    The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
    Windows SharePoint Service 3.0的某个Web Application无搜索结果
    网络连接不上, 有TCP错误, 如果操作系统是Windows Server 2003, 请尝试一下这里
    在WinDBG中查看内存的命令
    The virtual machine could not be started because the hypervisor is not running
  • 原文地址:https://www.cnblogs.com/lgjbky/p/14345915.html
Copyright © 2011-2022 走看看