拔掉网线时Socket的检查方法
最近在做一個(gè)TCP采集程序,使用到C/S的結(jié)構(gòu)。功能比較的簡(jiǎn)單,就是TCP采集程序作為服務(wù)器,信令采集設(shè)備作為客戶端,客戶端與服務(wù)器端之間建立長(zhǎng)連接之后,開始發(fā)送信令報(bào)文給服務(wù)器。在服務(wù)器端使用多線程方式來處理每個(gè)客戶端的socket連接,服務(wù)器端不主動(dòng)斷開鏈路,也沒有心跳機(jī)制來維護(hù)連接的狀態(tài),客戶端發(fā)送數(shù)據(jù)的時(shí)間也是不一定的,只要有采集到信令數(shù)據(jù)時(shí)才進(jìn)行發(fā)送。在客戶端socket斷開后,服務(wù)器端應(yīng)該能夠知道并且釋放socket資源。
判斷socket是否已經(jīng)斷開的方法是使用非阻塞的select方式進(jìn)行socket檢查,步驟如下:
1)設(shè)置接收到的socket為異步方式;
2)使用select()函數(shù)測(cè)試一個(gè)socket是否可讀;
3)如果select()函數(shù)返回的值為1,但是使用recv()函數(shù)讀取的數(shù)據(jù)長(zhǎng)度為0,那么說明該socket已經(jīng)斷開。
如果recv()返回值小于等于0時(shí),客戶端的連接已經(jīng)斷開,但是還需要判斷errno是否等于EINTR。如果errno=EINTR則說明recv()函數(shù)是由于程序接收到中斷信號(hào)后返回的,socket連接應(yīng)該還是正常,步應(yīng)該close掉socket連接。
?????? 注:對(duì)于阻塞socket的recv函數(shù)會(huì)在以下三種情況下返回值:
1)接收到數(shù)據(jù)時(shí)會(huì)返回;
2)程序接收到信號(hào)時(shí)返回-1,errno=EINTR;
3)Socket出現(xiàn)問題時(shí),返回-1,具體的錯(cuò)誤碼請(qǐng)查看man recv;
4)一定要養(yǎng)成查看man說明,內(nèi)容很詳細(xì),很有幫助。
這種方法經(jīng)過長(zhǎng)時(shí)間的測(cè)試證明是有效的,僅供大家參考。
此外,UNP卷一上有很多socket異常情況下的模擬解釋,大家可以去閱讀下。如果網(wǎng)絡(luò)中間有多級(jí)路由,路由當(dāng)?shù)舻群芏嗲闆r出現(xiàn),所以建議程序中在應(yīng)用層中加入心跳(heartbeat機(jī)制)和重連來維持連接的狀態(tài)。
TCP protocol has a timer to determine if the connection is abnormally closed. But this timeout value is very long by default and if you want to check this situation as soon as possible to improve performance, the best solution is to introduce a keepalive mechanism in application protocol design.
TCP協(xié)議有一個(gè)定時(shí)器來決定連接是否被異常關(guān)閉。但是該超時(shí)時(shí)間值缺省的情況下會(huì)非常長(zhǎng),如果你希望盡快的檢查出這種狀態(tài)改進(jìn)性能,最好的方法就是在應(yīng)用程序協(xié)議設(shè)計(jì)的時(shí)候引入keepalive(保持連接)機(jī)制。
總結(jié)
以上是生活随笔為你收集整理的拔掉网线时Socket的检查方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TCP网络编程中connect()、li
- 下一篇: c语言中%hu,%hx是什么意思