2015-12-08 30 views
-1

我有一個客戶端/服務器程序。客戶端運行良好。但是,當客戶端得到10060錯誤時,服務器似乎在accept()處發生故障,並且無法獲得返回值。我怎樣才能解決這個問題?我需要accept()來返回一個錯誤,以便服務器可以繼續做其他的事情。套接字接受後無法獲得返回值()

客戶端代碼:

SOCKET sock, sendrecv; 
sendrecv = myInitClientSocket(szIP, 6666); 
if (sendrecv ==0){ //socket 10060 error so that myInitClientSocket returns 0 
    int err= WSAGetLastError(); 
    shutdown(sendrecv, 0x02); 
    closesocket(sendrecv); 
    return 0; 
}  

服務器代碼:因爲這個調用應該阻塞進程的執行,並等待客戶

SOCKET sock, sendrecv; 
struct sockaddr_in sock_addr,sendrecv_addr; 
WSADATA data; 
WORD p; 
p=MAKEWORD(2,2); 
int resStartup = WSAStartup(p,&data); 
sock = WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0); 
int nREUSEADDR = 1; 
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&nREUSEADDR,sizeof(int)); 

sock_addr.sin_family=PF_INET; 
sock_addr.sin_port=htons(6666);   
sock_addr.sin_addr.s_addr=INADDR_ANY; 
int resBind = bind(sock,(struct sockaddr*)&sock_addr,sizeof(struct sockaddr_in)); 
int resListen =listen(sock, 5); 
int lun = sizeof (struct sockaddr); 
sendrecv = accept(sock,(struct sockaddr*)&sendrecv_addr,&lun); //stucking here 
if(sendrecv == INVALID_SOCKET ) 
{ 
    //can't go in here 
    return 5 ; 
} 
+0

錯誤10060指示嘗試連接到服務器失敗,例如,由於網絡出現故障或因爲它被防火牆阻止。服務器無法知道客戶端正在嘗試連接,因此accept()仍在等待連接。 –

+0

'accept'在有連接時返回,並且您的客戶端沒有連接(因爲導致它無法連接的某些錯誤)。你期望發生什麼? – immibis

+0

@HarryJohnston在這種情況下,我需要一個處理這種情況的機制。例如,10分鐘後服務器將停止接受,返回一個值並做其他事情。 –

回答

5

accept呼叫不能回報你一個值到達。如果你什麼都不做,客戶端也不會出現,accept不會永遠返回。

你所需要的就是

  1. 使用select之前accept,看是否有可用的待處理的客戶。

  • 使用setsockopt設置SO_SNDTIMEO和/或SO_RCVTIMEO的選項,使accept退出後的一段時間,甚至立即。
  • 實施細節可以在這裏找到:How to accept socket with timeoutSetting Socket Timeout?

    +0

    我在accept()之前使用select()。它工作完美!謝謝! –