1. 程式人生 > >SOCKET 檢測連結是否斷線的三種方法

SOCKET 檢測連結是否斷線的三種方法

目前主要有三種方法來實現使用者掉線檢測:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat執行緒。
下面我就上面的三種方法來做一下介紹。
(1)SO_KEEPALIVE 機制
        這是socket庫提供的功能,設定介面是setsockopt API:
   BOOL bSet=TRUE;
   setsockopt(hSocket,SOL_SOCKET,SO_KEEPALIVE,(const char*)&bSet,sizeof(BOOL));

       根據MSDN的文件,如果為socket設定了KEEPALIVE選項,TCP/IP棧在檢測到對方掉線後,
   任何在該socket上進行的呼叫(傳送/接受呼叫)就會立刻返回,錯誤號是WSAENETRESET ;
   同時,此後的任何在該socket控制代碼的呼叫會立刻失敗,並返回WSAENOTCONN錯誤。

   該機制的缺點也很明顯:
         預設設定是空閒2小時才傳送一個“保持存活探測分節”,不能保證實時檢測!
   當然也可以修改時間間隔引數,但是會影響到所有開啟此選項的套介面!
         關聯了完成埠的socket可能會忽略掉該套接字選項。


(2)SIO_KEEPALIVE_VALS 機制
         這是從彭博兄那裡學到一個機制拉,設定介面是WSAIoctl API:
     DWORD dwError = 0L ;
     tcp_keepalive sKA_Settings = {0}, sReturned = {0} ;
     sKA_Settings.onoff = 1 ;
     sKA_Settings.keepalivetime = 5500 ; // Keep Alive in 5.5 sec.
     sKA_Settings.keepaliveinterval = 3000 ; // Resend if No-Reply
     if (WSAIoctl(skNewConnection, SIO_KEEPALIVE_VALS, &sKA_Settings,
          sizeof(sKA_Settings), &sReturned, sizeof(sReturned), &dwBytes,
          NULL, NULL) != 0)
     {
           dwError = WSAGetLastError() ;
     }
     實現時需要新增tcp_keepalive and SIO_KEEPALIVE_VALS的定義檔案MSTCPiP.h
     該選項不同於SO_KEEPALIVE 機制的就是它是針對單個連線的,對系統其他的套接
     口並不影響。
        針對完成埠的socket,設定了SIO_KEEPALIVE_VALS後,啟用包由TCP STACK來負責。
     當網路連線斷開後,TCP STACK並不主動告訴上層的應用程式,但是當下一次RECV或者SEND操作
     進行後,馬上就會返回錯誤告訴上層這個連線已經斷開了.如果檢測到斷開的時候,在這個連線
     上有正在PENDING的IO操作,則馬上會失敗返回.


     該機制的缺點:
             不通用啦。MS的API只能用於Windows拉。不過,呵呵用彭博兄的評論就是:
     優雅一些^_^.
   
(3)Heart-Beat執行緒
        沒說的。自己寫一個後臺執行緒,實現Heart-Beat包,客戶端受到該包後,立刻返回相應的反饋 包。

    該方法的好處是通用,但缺點就是會改變現有的通訊協議!

轉自:http://hi.baidu.com/lewutian/item/b07797c2ec258c61f6c95dfb

參考1:


參考2:http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/

相關推薦

SOCKET 檢測連結是否方法

目前主要有三種方法來實現使用者掉線檢測:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat執行緒。 下面我就上面的三種方法來做一下介紹。 (1)SO_KEEPALIVE 機制         這是socket庫提供的功能,設定介面是se

SOCKET 檢測連結是否方法(轉載)

   目前主要有三種方法來實現使用者掉線檢測:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat執行緒。下面我就上面的三種方法來做一下介紹。(1)SO_KEEPALIVE 機制        這是socket庫提供的功能,設定介面是setsockopt API:   BO

Linux下執行時呼叫動態連結庫.so的方法(筆記)

在/etc/ld.so.conf.d/下建立xxx.conf,在文字中加入.so所在路徑,如:/usr/xxx等等,然後使用相應ldconfig命令使之生效。 將.so所在路徑新增為LD_LIBRARY_PATH環境變數。 在編譯命令中使用-Wl,-rpath

WCF檢測客戶端方法

       一般檢測客戶端斷線重連的方法都是使用心跳檢測。然而增加心跳檢測將會稍微影響系統的效能,總之這點資源開銷的瑕疵對於有強迫症的我來說有點難接受。在WCF裡面其實可以實現客戶端斷線檢測,而不需

java中創建程的方法以及區別

sta tar ati 定義 callable main ring 我們 () Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。Java可以用三種方式來創建線程,如下所示: 1)繼承Thread類創建線程 2)實現Runnable接口

Java創建多程的方法

exec 直接 驗證 stat scheduled href 後臺線程 ble nbsp   Java多線程實現方式主要有三種:繼承Thread類、實現Runnable接口、使用ExecutorService、Callable、Future實現有返回結果的多線程。其中前兩種

Unity之C#——非同步委託開啟執行緒,方法檢測結束

Unity之C#——非同步委託開啟執行緒,三種方法檢測結束 原始碼如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using

Linux 程同步的方法(互斥鎖、條件變量、信號量)

另一個 雙向 fin lee ces 僅支持 lin from str 互斥鎖 1 #include <cstdio> 2 3 #include <cstdlib> 4 5 #include <unistd.h> 6

Python實現"相交連結串列"的方法

寫程式找尋兩個單鏈表開始相交的起點 For example, the following two linked lists: A: a1 → a2 ↘ c1 → c2 →

連結串列反轉(Java實現方式)

Mackyhuang 連結串列這個資料結果經常遇見,這裡提供一個連結串列反轉的java程式碼實現,有三種演算法,一種是遞迴的,倆種是非遞迴的。 首先為了方便測試,在博文最後貼上遞迴實現連結串列建立的程式碼,以供讀者快速上手測試,提供的程式碼可以複製以後直接測

方法判斷連結串列是否為迴文結構

判斷連結串列是否是迴文結構:如1->2->3->2->1則是迴文結構 目錄 方法1:時間複雜度O(n),空間複雜度O(N),使用N個額外空間 最簡單 方法2:時間複雜度O(n),空間複雜度O(N),使用N/2個額外空間 方法3:時間複雜度O(n),空間複雜度O

合併兩個有序連結串列,合併後依然有序 --- 方法

1.合併連結串列p1,p2到p1上 void CombineList(ListNode** p1,ListNode* p2)//合併連結串列p1,p2 到p1 { if (*p1 == NULL) { *p1 = p2;

RecyclerView設定分隔方法

一、最簡單的方法(佈局劃線) 在item.xml檔案中在最下方指定一條分割線,例如: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res

【leetcode】迴文連結串列(Palindrome Linked List)【python】方法

題目連結 時間複雜度O(N),空間複雜度O(N) class ListNode: def __init__(self, x): self.val = x se

連結串列插入的方式

連結串列的插入: 一、頭插 1、判斷空鏈 : a:新節點指向NULL b: 頭指向新節點 2、非空鏈 a: 新節點指向頭(第一個節點) b: 頭指向new 綜上

socket I/O上設定超時的方法及其比較

        在socket I/O上設定超時, 一般有三種方法, 下面我們來聊聊。       1.  select/poll        這是最好的方法, 也是最為推薦的, 對於send/sendto和recv/recvfrom, 都可以用select和poll來設定

python中socket接受資料的方法

原位置:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408859 Description: An issue with socket.recv is how to know when you are don

Unity 使用物理射線(Physics.Raycast),實現扇形區域碰撞檢測方法

Unity 使用物理射線(Physics.Raycast),實現扇形(Fan-Shaped)區域碰撞檢測。   網上已經很多實現扇形檢測的方法。大部分都是用MeshCollider實現的。而據說MeshCollider這東西很耗效能(沒有親測),所以就用射

資料結構之程式效能檢測(一):排序演算法·對比

先上程式碼: #include<stdio.h> #include<time.h> # define MAX_SIZE 1001 void sort(int *a, int n); void sort2(int *a, int n)

建立圖的方法(鄰接矩陣+鄰接表+十字連結串列)

一、鄰接矩陣 採用矩陣的方式來描述圖中的連線各非連線關係,若不能連上用無窮大或者0來表示,但是如果邊很稀少,頂點很多,那麼將會有很大的浪費。同時,這個矩陣可以同時刻畫有向圖和無向圖,無向圖就是把有向圖根據對角線對稱即可。 1、思想:建立一個結構體,它包含