Tcp服務端判斷客戶端是否斷開連接


     今天搞tcp鏈接弄了一天,前面創建socket,綁定,監聽等主要分清自己的參數,udp還是tcp的。好不容易調通了,然后就是一個需求,當客戶端主動斷開連接時,服務端也要斷開連接,這樣一下次客戶端請求鏈接的時候才能成功鏈接。

      然后就開始找各種方法。其中簡單的是看recv()返回為0,表明斷開了鏈接,但是recv函數始終返回SOCKET_ERROR,找不到原因。。。。。。。。。。。。

      現在已經調通了,就是recv()==0時,斷開連接。先主要是沒有用accept()的socket,當然接收不到東西。。。

參考的方法: 下面來羅列一下判斷遠端已經斷開的方法:

法一: 當recv()返回值小於等於0時,socket連接斷開。但是還需要判斷 errno是否等於 EINTR,如果errno == EINTR 則說明recv函數是由於程序接收到信號后返回的,socket連接還是正常的,不應close掉socket連接。

 

法二:

struct tcp_info info;

int len=sizeof(info);

getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); if((info.tcpi_state==TCP_ESTABLISHED)) 則說明未斷開 else 斷開

 

法三: 若使用了select等系統函數,若遠端斷開,則select返回1,recv返回0則斷開。其他注意事項同法一。

法四:

int keepAlive = 1; // 開啟keepalive屬性

int keepIdle = 60; // 如該連接在60秒內沒有任何數據往來,則進行探測

int keepInterval = 5; // 探測時發包的時間間隔為5 秒

int keepCount = 3; // 探測嘗試的次數.如果第1次探測包就收到響應了,則后2次的不再發.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));

setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));

setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

設置后,若斷開,則在使用該socket讀寫時立即失敗,並返回ETIMEDOUT錯誤

 

法五: 自己實現一個心跳檢測,一定時間內未收到自定義的心跳包則標記為已斷開。 參考:http://www.cppblog.com/luketowne/articles/77780.html http://www.blogjava.net/thisliy/archive/2010/02/17/313271.html http://blog.csdn.net/henry000/article/details/7250866


免責聲明!

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



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