TCP建立连接过程、状态以及连接队列

一、连接过程与状态 

1、各状态解释:

     CLOSED:没有任何连接状态

     SYN-SENT:在发送连接请求后,等待对方确认

     LISHEN:监听状态,等待客户端TCP端口的连接请求

     SYN-RECEVED:接收到客户端发来的连接请求,已发送连接请求,等待对方确认

     ESTABLISHED:代表传输连接建立,双方进入数据传送状态

----------------------------------------------------------------------------------------------------

     FIN-WAIT1:主动关闭,客户端已发送关闭连接请求,等待服务器确认

     FIN-WAIT2:主动关闭,客户端已收到服务器关闭传输连接确认,等待对方发送关闭传输连接请求

     TIME-WAIT:完成双向连接传输关闭,等待所有分组消失

     CLOSE-WAIT:被动关闭,收到对方发来的关闭连接请求,并已确认

     LAST-ACK:被动关闭,等待最后一个关闭传输连接确认,并等待所有分组消失

     CLOSING:双方同时尝试关闭传输连接,等待对方确认。

2、查看linux进程的TCP通信状态

使用命令:ss -ntap

参数解析:
   -n, --numeric       don't resolve service names  
    //这里的意思是不解析【:port】项的端口号为服务名
   -t, --tcp           display only TCP sockets
   -a, --all           display all sockets
    //不加a默认只查看ESTAB状态
   -p, --processes     show process using socket

 

iptables与ssh命令结合,查看SYN-SENT状态

在A上使用iptables命令丢弃目的地址为B的数据包,A与B尝试建立SSH通信,在A上查看状态:

在A上:

iptables -A OUTPUT -d 192.168.80.99 -j DROP

ssh 192.168.80.99

查看状态:ss -nta

3、客户端先发送一个FIN给服务器,自己进入FIN-WAIT1状态,等待接收服务器端报文,这时会出现三种可能:

      ① 只有服务器端的ACK

        只收到服务器的ACK,客户端会进入FIN-WAIT2状态,后续当收到服务器端的FIN时,回应发送一个ACK,进入TIME-WAIT状态,这个状态会持续保留2MSL(TCP报文在网络中的最大生存时间)。

      ② 只有服务器端的FIN

       客户端回应ACK给服务器,进入CLOSING状态,接收到服务器ACK时,进入TIME-WAIT状态。

      ③ 既有ACK,又有FIN

        同时收到服务器端的ACK和FIN,直接进入TIME-WAIT状态。

二、sysns queue 与 accept queue

1、syns queue

        当服务器接收到客户端第一次SYN连接请求时,将创建的request_sock结构存储在syns半连接队列中,然后向客户端发送【SYN,ACK】报文。此时服务器处于SYN-RECEVE状态。

2、accept queue

        当服务器收到客户端ACK时,将半连接队列相应条目删除,然后将相应的连接放入accept队列中,此时服务器端连接状态为ESTABLISTHENED。进入accept queue中的连接等待accept()调用。

3、linux内核中TCP的调优参数

查看帮助:man 7 tcp

示例:

①  查看和修改客户端的动态端口范围

cat /proc/sys/net/ipv4/ip_local_port_range
echo 32789 60999 > /proc/sys/net/ipv4/ip_local_port_range

② 查看和修改TCP的MSL

cat /proc/sys/net/ipv4/tcp_fin_timeout
sysctl net.ipv4.tcp_fin_timeout=80

③ 查看syns queue和syns queue队列长度

cat /proc/sys/net/ipv4/tcp_max_syn_backlog   
//syns queue大小,默认值128
cat /proc/sys/net/core/somaxconn      
//accept queue大小,默认值128

三、python实现简易版TCP通信

客户端:

import socket

# 1 创建socket
sock = socket.socket()
# 2 连接
addr = ("127.0.0.1", 8088)
sock.connect(addr)    #完成TCP三报文握手
# 3 数据处理
msg = "hello, im the client.".encode("utf-8")
sock.send(msg)
data = sock.recv(1024)
print("接收:", data.decode())
# 4 断开连接 释放资源
sock.close()

服务端:

import socket
# 1 创建socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock = socket.socket()
# 2 绑定
addr = ("0.0.0.0", 8088)
sock.bind(addr)
# 3 监听
sock.listen(1)  #设置最长半连接数队列数长度为1
print("服务器正在监听...",addr)

while True:
    # 4 接受连接
    conn, addr_client = sock.accept()  #全连接队列中取出连接
    print("已连接", addr_client)
    # 5 数据处理(接受数据,发送数据)
    data = conn.recv(1024)
    print("收到:", data.decode("utf-8"))
    msg = "i am the server。".encode("utf-8")
    conn.send(msg)
    # 断开连接
    conn.close()

# 6 释放资源
sock.close()

参考链接:

图解 TCP 三次握手:一步步构建网络会话-51CTO.COM

TCP半连接队列和全连接 - zh1164 - 博客园

Python 网络编程 | 菜鸟教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值