2017-09-19 75 views
1

我有一個簡單的udp客戶端/服務器程序。UDP客戶端不會自動重新連接

如果客戶端丟失連接或服務器正在重新啓動,客戶端將不會自動重新連接。我總是必須手動重新啓動客戶端。

這是我的客戶端套接字配置:

struct sockaddr_in si_other; 
int s, i, j, slen=sizeof(si_other); 
char buf[BUFLEN]; 
char message[BUFLEN] = "0"; 

if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) 
    die("socket"); 

memset((char *) &si_other, 0, sizeof(si_other)); 
si_other.sin_family = AF_INET; 
si_other.sin_port = htons(PORT); 

這是我的無限循環的主要部分:

if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1) 
    die("sendto()"); 

//clear buf 
memset(buf,'\0', BUFLEN); 

//try to receive some data, this is a blocking call 
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) 
    die("recvfrom()"); 

做一些研究之後,我試圖改變插座模式無 - 通過添加以下行來屏蔽:

fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0 | O_NONBLOCK); 

客戶端現在能夠發送一個messa ge到服務器,但客戶端沒有收到任何答案。該錯誤信息是:

recvfrom的():資源暫時不可用

+6

UDP套接字根本不建立連接 – bukkojot

+0

是關於'EGAIN'錯誤嗎? 'recvfrom()'操作會有* blocked *,但由於套接字是*非阻塞*,它會立即返回。 –

+0

@bukkojot是的,對不起的措辭抱歉。客戶端以無限循環發送消息。我的目標是當服務器不可用幾秒鐘時,客戶端應該繼續發送消息。 – localhorst27

回答

0

下面的解決方案正常工作:

插入無限循環之前執行以下操作:

struct timeval tv; 

tv.tv_sec = 1; 
tv.tv_usec = 0; 
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof(struct timeval)); 

由於功能die()打印錯誤消息並停止該程序,我不得不更換以下內容:

if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) 
    die("recvfrom()"); 

if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) 
    printf("no response from the server!"); 

recvfrom()仍然是現在一個阻塞調用,但僅限於1秒。以前這是一個永久的阻塞呼叫,這是唯一的問題。

相關問題