TCP建立与断开连接、SOCKET通讯模板

三次握手、四次挥手

传输层中,TCP建立传输链接时的三次握手和关闭链接的四次挥手,因为socket工作于应用层和传输层之间,所以涉及建立链接和关闭链接的过程

TCP使用窗口机制进行流量控制,什么是窗口?

连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端;接收方发送的确认信息中包含了自己剩余的缓冲区尺寸;剩余缓冲区空间的数量叫做窗口

 

LISTEN - 服务器侦听来自客户端TCP端口的连接请求; 
SYN-SENT - 客户端在发送连接请求后等待匹配的连接请求; 
SYN-RECEIVED -  服务器在收到和发送一个连接请求后等待对连接请求的确认; 
ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
CLOSE-WAIT - 等待从本地用户发来的连接中断请求;

 

FIN-WAIT-2 - 从远程TCP等待 连接中断请求; 
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 
TIME-WAIT - 等待足够的时间以确保远程TCP接收到连接中断请求的确认; 
CLOSED - 关闭,没有任何连接状态;

三次握手:

TCP/IP协议中,TCP协议采用三次握手建立一个连接。

(1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

确认号:其数值等于发送方的发送序号 +1(即接收方期望接收的下一个序列号)。

四次挥手:

TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。

客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

详细过程:
    第一阶段   客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i;
    1.服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道;
    2.客户机收到ACK(i+1)后,关闭客户机写通道;
   (此时,客户机仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据)
    第二阶段 服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j;
    3.客户机收到FIN(j)后,返回确认段ACK,序列号为j+1,关闭客户机读通道;
    4.服务器收到ACK(j+1)后,关闭服务器写通道。
这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。
FIN标识是通过发送最后一块数据时设置的,标准的例子中,服务器还在发送数据,所以要等到发送完的时候,设置FIN(此时可称为TCP连接处于半关闭状态,因为数据仍可从被动关闭一方向主动关闭方传送)。

socket通讯模板

import socket

# 创建
server = socket.socket()
# 绑定
server.bind(("192.168.12.154", 20000))
# 监听
server.listen()  # 指定半连接数 默认则由操作系统决定

while True:
    #  接收,client:客户端的client对象 type为<class 'socket.socket'>,addr:客户端的("ip",端口号)
    client, addr = server.accept()
    while True:
        # 捕获异常  主要有 客户端强行关闭
        try:
            # 接收消息  可以理解为 双向通讯,在服务端有个client的同类负责和客户端里自己的同类交流 server请了个助手
            data = client.recv(1024)
            print(type(client), addr)
            if not data:  # 避免客户端正常close()后 没有send 但是服务端某种情况下不断执行data = client.recv(1024) 打印空data
                client.close()
                break
            print("来自客户端:", data.decode("utf8"))
            # 反馈消息
            client.send(input(">>>").encode("utf8"))
        except ConnectionResetError:
            print("客户端强行终止了通讯")
            client.close()
            break

# while True在实际中是有条件终止的 终止后需要执行close()
server.close()
tcp 服务端
import socket

# 创建
client = socket.socket()
# 连接服务端
client.connect(("192.168.12.154", 20000))

while True:
    msg = input(">>>")
    # 发送
    client.send(msg.encode("utf8"))
    # 接收服务端回执的数据
    data = client.recv(1024)
    print("服务端:", data.decode("utf8"))

# while True在实际中是有条件终止的 终止后需要执行close()
client.close()
tcp 客户端
原文地址:https://www.cnblogs.com/dongzhihaoya/p/10172010.html