我正在開發一個帶有執行緒的 TCP 客戶端服務器應用程式,其中客戶端輪流向服務器發送訊息(類似于基于回合的游戲)。服務器向客戶端發送訊息,但客戶端有n秒的時間回應。如果客戶端沒有及時回應,服務器應該在不關閉連接的情況下轉到下一個客戶端。有沒有辦法跳過服務器的read()呼叫?
uj5u.com熱心網友回復:
關于服務器跳過呼叫的含義尚不清楚read(),但我認為您正在談論實作您描述的回應超時。一種常見的方法是使用該select()函式,它允許您等待指定的時間量,以便檔案描述符準備好。然后,您將根據所需檔案描述符是否已準備就緒的信號來選擇是繼續read()還是繼續下一個客戶端。select()
非常粗略地說,這可能是這樣的:
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
// ...
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(client_fd, &read_fds);
struct timeval timeout = { .tv_sec = 5, .tv_usec = 0 };
int num_ready = select(client_fd 1, &read_fds, NULL, NULL, &timeout);
if (num_ready == -1) {
// handle error ...
} else if (num_ready == 0) {
// handle timeout ...
} else if (num_ready == 1) {
// handle client response ...
} else {
// should not happen
assert(0);
}
您還可以考慮select()具有類似行為的替代方法,例如poll()和epoll_wait()。此外,您可能會發現將客戶端套接字配置為非阻塞 I/O 是有利的,盡管這不是使用select(), etc的技術要求。職能。
但是請注意,它比這更復雜。至少有這些額外的考慮:
您需要為客戶端斷開連接的情況做好準備。
如果客戶端的回應到達太晚,那么您將需要讀取該回應并(可能)丟棄它,然后才能處理來自同一客戶端的任何后續回應。
回應可能在線路上被分成多個部分,因此回應的開始可能會在超時內到達,但結束可能不會,甚至可能根本不會到達。
為了穩健性,您需要處理在時間到期之前等待被信號中斷的情況。在這種情況下,您可能希望恢復等待,但不重新啟動超時。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410346.html
標籤:
上一篇:C蘭德()。生成隨機字串的問題
