今天搞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