我在Unix上有一個基於telnet的服務器的間歇性問題(這個問題在AIX和Linux上都出現了)。 服務器打開兩個套接字,一個連接到客戶端telnet會話,另一個連接到與服務器在同一臺計算機上運行的程序。這個想法是數據通過服務器傳遞給這個程序和從這個程序傳遞過來。選擇和讀取套接字(Unix)
當前設置有一個循環,使用select等待「讀取」文件描述符變爲可用,然後使用select等待「寫入」文件描述符變爲可用。
然後程序從傳入的文件描述符中讀取數據,然後在寫入輸出描述符之前處理數據。
下面的代碼片段顯示了發生了什麼。問題在於偶爾讀取失敗,並將errno設置爲ECONNRESET或ETIMEDOUT。這些都不是通過閱讀記錄的代碼,所以它們來自哪裏?
真正的問題是,我該如何阻止這種情況發生,或者優雅地處理它? 可以做兩個連續的選擇是問題嗎?
當前的處理行爲是關閉並重新啓動。需要注意的一點是,一旦發生這種情況,通常會發生三次或四次,然後清理。系統負載似乎不是那麼高(這是一個大的服務器)。
if (select(8, &readset, NULL, NULL, NULL) < 0)
{
break;
}
if (select(8, NULL, &writeset, NULL, NULL) < 0)
{
break;
}
if (FD_ISSET(STDIN_FILENO, &readset)
&& FD_ISSET(fdout, &writeset))
{
if ((nread = read(STDIN_FILENO, buff, BUFFSIZE)) < 0)
{
/* This sometimes fails with errno =
ECONNRESET or ETIMEDOUT */
break;
}
}
你知道,你可以將這兩個'select'調用合併爲一個。另外,'select'的第一個參數應該是set + 1中的最大fd,而不是8.同樣,stdin是套接字嗎? – Hasturkun
返回ETIMEDOUT的STDIN_FILENO是不尋常的。你在做什麼特別的事情嗎? (重定向,fcntls等)? – cnicutar
我建議你從實施Hasturkun的建議開始,如果處理不當,選擇可能會相當溫和。 – fvu