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 等等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM