tcp连接检测-keep-alive

断线检测

tcp的断线检测,是分为两种的:

     利用tcp自带的keep –alive机制

     自己组建心跳包的方式向对端发送

Keep_alive机制

通过Keep-alive机制对tcp的连接保持,也就是Tcp的心跳包,见MSDN

If keep-alive is enabled for a TCP socket with SO_KEEPALIVE, then the default TCP settings are used for the keep-alive timeout and interval unless these values have been changed by calling the WSAIoctl function with the SIO_KEEPALIVE_VALS option. The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.

也就是说协议栈会在2小时后发送向对端发送请求包。默认情况下,此Keep-alive机制是关闭的。

自己发送心跳包机制

自己发送心跳包,在程序内一般采用多线程,检测最后发送(或者接收包)的时间,超过一定时间,则发送心跳包。

由此产生疑问:

为什么都是采用的发送的方式?

TCP原理

TCP原理应该都不陌生,但是其本质的还是对端数据包的发送,常听人说,TCP有链路,其实TCP是没有链路的,系统对数据包的判定(判断从哪个机器的哪个程序发送的),其实是通过(本端ip+本端port+对端ip+对端port)hash值来判定的,系统根据这个值在协议栈内保存着每个socket的状态,比如当前接收了多少字节等等信息。

Keep_alive机制默认关闭的影响

Keep-alive默认下是关闭的,也就是本端与对端是除非程序主动send,是不会发送数据包(心跳包),既是,处理本端与对端的系统里的socket状态是不会变化,这里,如果对端当机(或者网线断掉),本端是无法知道对端socket已经关闭,所以本端的socket会一直的存在。

 

复制代码
View Code 
import socket

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('0.0.0.0', 8001))
    sock.listen(5)
    while True:
        print 'here:'
        conn, address = sock.accept()
        buf = conn.recv(1024)
        print 'buf:' + str(len(buf))
        if len(buf) <= 0:
            print 'conn close:', conn
复制代码

 

客户端采用如下步骤:

1, 连接

2, 拔掉网线

经过以上两步: 

 

从上图中可以看到,此时服务端的连接依然存在。 

所以,tcp只是数据的发送与接收,包括握手,断开以及rst,time_wait,close_wait 等等。

 

posted @   connoryan  阅读(13698)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示