我正在使用Linux系統(使用2.6.20內核的Ubuntu 7.04服務器)。選擇UDP套接字在套接字關閉時不會結束 - 我做錯了什麼?
我有一個程序,有一個線程(thread1)等待UDP套接字的選擇變得可讀。 我使用select(與我的套接字作爲單個readfd和單個exceptfd),而不是僅僅調用recvfrom,因爲我想要超時。
從另一個線程中,我關閉並關閉了套接字。 如果我在recvfrom中阻止thread1時執行此操作,recvfrom將立即終止。 如果我這樣做,而thread1被阻塞在一個超時選擇,那麼選擇不會立即終止,但最終會正常超時。
任何人都可以告訴我爲什麼選擇不會在套接字關閉時退出?這不是例外嗎?我可以看到它不可讀(顯然),但是它是封閉的,這似乎是可以忽略的。
這裏的插座的開口(處理去除所有的錯誤讓事情變得簡單):
m_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
struct sockaddr_in si_me;
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(m_sockfd, (struct sockaddr *)(&si_me), sizeof(si_me)) < 0)
{
// deal with error
}
這裏的SELECT語句線程1執行:
struct timeval to;
to.tv_sec = timeout_ms/1000;// just the seconds portion
to.tv_usec = (timeout_ms%1000)*1000;// just the milliseconds
// converted to microseconds
// watch our one fd for readability or
// exceptions.
fd_set readfds, exceptfds;
FD_ZERO(&readfds);
FD_SET(m_sockfd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(m_sockfd, &exceptfds);
int nsel = select(m_sockfd+1, &readfds, NULL, &exceptfds, &to);
更新:顯然,(如下所述),關閉套接字並不是一個例外情況(從select的角度來看)。我想我需要知道的是:爲什麼?而且,這是故意的嗎?
我真的很想理解這個選擇行爲背後的想法,因爲它似乎與我的期望相反。因此,我顯然需要調整我對TCP堆棧如何工作的思考。請給我解釋一下。
這將是一個很好的解決方案。在套接字和管道上都選擇等待,另一個線程將寫入管道以使選擇返回。 – 2009-01-26 19:57:49