2013-10-18 45 views
0

這是我的情況,我使用的是UDP,並且有一臺服務器向我發送數據,但由於數據包丟失,他也可能無法發送數據,像他重新發送它,但我的客戶也可能不會收到數據,所以我希望他重新閱讀它。就目前而言,我決定暫停我的客戶,他將等待一段時間,然後重新閱讀。我的問題是,只是簡單地添加一個跳回到選擇去解決問題,或將選擇在第一次超時後中斷?我是否必須使套接字非阻塞?我在網上的某個地方讀到這個消息。從本質上講,我的目標是,如果閱讀不發生,在一段時間後再試一次,因爲我知道發件人正試圖發送。我想知道我的邏輯是否正確,因爲我沒有辦法測試它。使用時讀取時發生超時選擇

fd_set set; 
    struct timeval timeout; 
    int rv; 
    char buff[100]; 
    int len = 100; 

    FD_ZERO(&set); /* clear the set */ 
    FD_SET(sockfd, &set); /* add our file descriptor to the set */ 

    timeout.tv_sec = 0; 
    timeout.tv_usec = 10000; 

    retry: 
    write(sockfd,"hi",3);//sent to client now waiting for an ack 
    rv = select(sockfd + 1, &set, NULL, NULL, &timeout); 
    read(sockfd, buff, strlen(buff), 0); 
    if(rv == -1) 
    perror("select"); /* an error accured */ 
    else if(rv == 0) 
    printf("timeout"); 
    goto retry; 
    else 
    read(filedesc, buff, len); /* there was data to read */ 
} 
+0

爲什麼filedesc + 1? – LostBoy

+1

@LostBoy這是如何選擇作品 – user2879618

+0

是的,剛剛發現;) – LostBoy

回答

1

我會excpect是選擇修改您的fd_set所以它不讀取後包含您的sockfd了(因爲它是不準備讀)。所以只是爲了確保在重試之前應該重新初始化該設置。或者你可以嘗試如果fd在超時後仍然存在,但我認爲正常的行爲是在調用select之前重新初始化所有的FD。 如果您使用投票或epoll,則不必這樣做。

除此之外,代碼看起來沒問題。

不管你是使用blockin還是nonblocking IO對你的情況來說都無關緊要。如果使用非阻塞,寫入可能會失敗,因此阻止更容易。