我必須爲我的IT學校製作一個簡單的IRC客戶端/服務器程序。該主題要求我們使用select(2)
進行套接字輪詢,但禁止我們使用O_NONBLOCK
套接字。我們可以用阻塞套接字做一個非阻塞的服務器嗎?
- 您的服務器將接受多個同時連接。
注意,禁止使用fork
。所以你應該使用select
- 你的服務器不能被阻塞。
這有什麼做與非阻塞套接字,這是禁止的(所以不要使用fcntl(s, O_NONBLOCK)
)
我想知道如果它甚至可以設計一個無阻塞服務器(哪些不叉)與阻塞插座,甚至使用select(2)
。
下面是一個簡單的例子:假設我們有一個簡單的文本協議,每行一個命令。每個客戶都有一個緩衝區。當select(2)
告訴我們一個客戶端準備好了read(2)
時,我們閱讀,直到我們在客戶端緩衝區中找到一個\n
,因此我們處理該命令。使用非阻塞套接字,我們將讀取到EAGAIN
。
現在想象一下,我們正在使用阻塞套接字,並且惡意客戶端發送沒有換行符的文本。 select(2)
告訴我們數據可用,然後我們在客戶端上read(2)
。但我們永遠不會讀取預期的\n
。系統調用不會返回EAGAIN
,而是無限期地阻塞。這是一項拒絕服務攻擊。
是否真的有可能設計一個無阻塞的服務器與阻塞插座和select(2)
(否fork(2)
)?
好的,這是有道理的;那麼你只需要做一個'read'調用,對吧? – 2015-03-25 02:53:21
當'select()'退出時,一個或多個套接字可能是可讀的,具體取決於您等待的套接字數量。你必須在每個可讀的套接字上調用'read()',根據需要緩存接收到的數據,然後在返回到'select()'前處理緩衝區。 – 2015-03-25 03:09:10
這隻考慮閱讀。你還需要考慮寫作。 – EJP 2015-03-25 03:22:48