<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    socket選項自帶的TCP異常斷開檢測

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    TCP異常斷開是指在突然斷電,直接拔網線等等情況下,如果通信雙方沒有進行數據發送通信等處理的時候,無法獲知連接已經斷開的情況.

      在通常的情況下,為了使得socket通信不受操作系統的限制,需要自己在應用層實現心跳包機制,來檢查異常斷開的情況,一般的方式就是服務器在一段時間沒有收到客戶端數據包時,定時發包,然后客戶端回應,如果已經出現異常斷開則服務器接收會返回錯誤,而客戶端在指定時間內沒有收到數據包,則主動向服務器發包,得到錯誤就說明斷開.諸如此類的方式就是自己實現的心跳包機制.

      但操作系統本身也自帶了一些心跳包機制,這些機制是由socket的TCP棧底層實現的,不會影響應用層通信,也不需要應用層自己處理,發現異常斷開可以自行檢查出來并返回錯誤(它的本質也是在空閑時發送心跳包).以下介紹一下Windows以及linux下的方法.

      首先介紹Windows下的方法,該方式要求通信雙方必須都是Windows NT以上操作系統(如果是其它版本操作系統,如linux等等,不敢保證100%無效).MSDN中有描述WSAIoctl中的SIO_KEEPALIVE_VALS選項,該選項以及struct tcp_keepalive的定義在MSTCPiP.h有,不進行說明了,直接看代碼:

     

        #include <MSTCPiP.h>

     

        DWORD retBytes;
        tcp_keepalive inKeepSetting;
        tcp_keepalive retKeepSetting;

        inKeepSetting.onoff = 1;                //探測次數
        inKeepSetting.keepalivetime = 5500;        // 首次探測開始前的tcp無數據收發空閑時間
        inKeepSetting.keepaliveinterval = 3000;    // 每次探測的間隔時間

        if (WSAIoctl(aptSock, SIO_KEEPALIVE_VALS, 
            &inKeepSetting,
            sizeof(inKeepSetting),
            &retKeepSetting,
            sizeof(retKeepSetting),
            &retBytes,
            NULL,
            NULL) != 0)
        {
            printf("WSAIoctl Error: %d/n", WSAGetLastError());
        }

     

      Linux下的方式是通過setsockopt來設置選項,見代碼(代碼從網絡上摘錄了部分):

      #include   <netinet/tcp.h> 
      ……

     

      #define SOCKET_ERROR (-1)

     

      // 以秒為單位
      int   keepAlive = 1;       //設定KeepAlive 
      int   keepIdle = 5;        //首次探測開始前的tcp無數據收發空閑時間
      int   keepInterval = 3;  //每次探測的間隔時間
      int   keepCount = 2;     //探測次數
                    
      if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == SOCKET_ERROR)

          printf("Call setsockopt error, errno is %d/n", errno);


      if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void   *)&keepIdle,sizeof(keepIdle)) == SOCKET_ERROR)

          printf("Call setsockopt error, errno is %d/n", errno);

      if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void   *)&keepInterval,sizeof(keepInterval)) == SOCKET_ERROR)

          printf("Call setsockopt error, errno is %d/n", errno);
                    
      if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void   *)&keepCount,sizeof(keepCount)) == SOCKET_ERROR)

          printf("Call setsockopt error, errno is %d/n", errno);

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全