1. 程式人生 > >如何判斷SOCKET還是連線著的

如何判斷SOCKET還是連線著的

1. read函式來判斷

讀到長度0不能斷定是已經斷開.除非是-1,才代表輸入流已經被關閉,說名socket已經close,而且關鍵在於你怎麼讀,實際上應該是一個單獨的執行緒一直在讀,因為你無法預先知道能不能一次將發過來的包讀完,也無法知道一次是不是讀完整了包,所以線稱一直迴圈在讀並且一直在解包.這樣即能知道什麼時候server,也完成了訊息的解讀,我的方案是這樣的,在大資料量高速率網路上執行沒有發生過丟包

// 判斷是否連線

char ch = 'A';

if (read(g_sockfd, &ch, 1)<=0)

{

if (connect(g_sockfd,(struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr) ) == 0)

{

ServiceLog.write_log("[NotifyDAU]:connect to DAUsuccess.");

}

else

{

ServiceLog.write_log("[NotifyDAU]:can't connect to DAU ");

return;

}

}

try{}catch{}是比較合適。

當他是連著的,當進行通訊時發生異常後就知道了.

當你不斷的read的時候,server,exceptioncatch到了。

2. 心跳包

可不可以在Client設一個定時器,每隔一段時間發一條訊息給伺服器,看能不能收到伺服器的響應。

心跳包就是定時發包,沒回應就判斷斷開。

3. getsockopt

int optval, optlen = sizeof(int);

getsockopt(sd, SOL_SOCKET, SO_ERROR,(char*) &optval, &optlen);

switch(optval){

case 0:

//“處於連線狀態“

break;

case ECONNREFUSED:

case EHOSTNUMREACH:

}

4. 專案中使用的情況

// 判斷是否連線

int optval, optlen = sizeof(int);

int r = getsockopt(g_sockfd, SOL_SOCKET, SO_ERROR,(char*) &optval, &optlen);

// send HELLO

if ((optval == 0) && (r == 0) && (send(g_sockfd,(char*)&g_DAUCommand,sizeof(struct _DAUCommand),0) != SOCKET_ERROR ))

{

ServiceLog.write_log("[threadOperationWaitTrasferAgain]: try to recv from dau...");

length = recv(g_sockfd,(char *)&command,sizeof(struct _DAUCommand),0);

}

else

{

if (connect(g_sockfd,(struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr) ) == 0)

{

ServiceLog.write_log("[threadOperationWaitTrasferAgain]:connect to DAUsuccess.");

ServiceLog.write_log("[threadOperationWaitTrasferAgain]: try to recv from dau...");

length = recv(g_sockfd,(char *)&command,sizeof(struct _DAUCommand),0);

}

else

{

ServiceLog.write_log("[threadOperationWaitTransferAgain]:can't connect to DAU, try again ");

length = 0;

continue;

}

}