1. 0 1 2 3
  2. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. | Source Port | Destination Port |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. | Sequence Number |
  7. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  8. | Acknowledgment Number |
  9. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  10. | Data | |U|A|P|R|S|F| |
  11. | Offset| Reserved |R|C|S|S|Y|I| Window |
  12. | | |G|K|H|T|N|N| |
  13. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. | Checksum | Urgent Pointer |
  15. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. | Options | Padding |
  17. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  18. | data |
  19. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

1.三次握手

  1. # 服务端
  2. import socket
  3. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. sock.bind(('127.0.0.1', 8001))
  5. sock.listen(5)
  6. while True:
  7. conn, addr = sock.accept() # 等待客户端连接
  8. ...
  1. # 客户端
  2. import socket
  3. client = socket.socket()
  4. client.connect(('127.0.0.1', 8001)) # 发起连接
  1. 客户端 服务端
  2. 1. SYN-SENT --> <seq=100><CTL=SYN> --> SYN-RECEIVED
  3. 2. ESTABLISHED <-- <seq=300><ack=101><CTL=SYN,ACK> <-- SYN-RECEIVED
  4. 3. ESTABLISHED --> <seq=101><ack=301><CTL=ACK> --> ESTABLISHED
  5. At this point, both the client and server have received an acknowledgment of the connection. The steps 1, 2 establish the connection parameter (sequence number) for one direction and it is acknowledged. The steps 2, 3 establish the connection parameter (sequence number) for the other direction and it is acknowledged. With these, a full-duplex communication is established.
  • 传输数据
    1. 在收发数据的过程中,只有有数据的传送就会有应答(ack),如果没有ack,那么内部会尝试重复发送。

    2.四次挥手

    关闭连接,客户端和服务端要进行4次挥手。 ```python import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((‘127.0.0.1’, 8001)) sock.listen(5) while True: conn, addr = sock.accept() … conn.close() # 关闭连接 sock.close()

  1. ```python
  2. import socket
  3. client = socket.socket()
  4. client.connect(('127.0.0.1', 8001))
  5. ...
  6. client.close() # 关闭连接
  1. TCP A TCP B
  2. 1. FIN-WAIT-1 --> <seq=100><ack=300><CTL=FIN,ACK> --> CLOSE-WAIT
  3. 2. FIN-WAIT-2 <-- <seq=300><ack=101><CTL=ACK> <-- CLOSE-WAIT
  4. 3. TIME-WAIT <-- <seq=300><ack=101><CTL=FIN,ACK> <-- LAST-ACK
  5. 4. TIME-WAIT --> <seq=101><ack=301><CTL=ACK> --> CLOSED


3.三次握手与四次挥手原理

  1. 0 1 2 3
  2. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. | Source Port | Destination Port |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. | Sequence Number(序列号,标识位置) |
  7. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  8. | Acknowledgment Number |
  9. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  10. | Data | |U|A|P|R|S|F| |
  11. | Offset| Reserved |R|C|S|S|Y|I| Window |
  12. | | |G|K|H|T|N|N| |
  13. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. | Checksum | Urgent Pointer |
  15. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. | Options | Padding |
  17. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  18. | data |
  19. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  20. 三次握手:
  21. 第一次(客户端--->服务端):syn(开启同步,建立连接),序列号 ----- 保证互相序列号
  22. 建立连接之后,的其他数据包,不用写syn syn = 1 seq是内容需要处理
  23. 第二次(服务端---->客户端):Acknowledgment Number = Sequence Number + 1 syn=1 和自己的seq num(序列号)
  24. ack = 1 ack num 有内容,需要处理
  25. 第三次(客户端--->服务端):看ack num 是否是刚才 seq num +1 ,如果是 ack num = seq num + 1 ACK=1
  26. 四次挥手:主动断开连接(客户端或者服务端)
  27. establish
  28. 客户端为例:
  29. ...客户端发了一个数据包,传到服务端MSL,传回MSL
  30. (客户端--->服务端):FIN = 1
  31. (服务端---->客户端):ACK = 1
  32. (服务端---->客户端):FIN = 1data
  33. (客户端--->服务端):ACK = 1 msl 任何报文被丢弃前在网络中存活的最长时间
  34. 等待 2msl 然后关闭
  35. network.sendToServer("ssss")