[英]Asynchronous server socket multiple clients
我一直在使用 msdn 上發布的以下代碼:
http://msdn.microsoft.com/en-us/library/fx6588te.aspx
我了解在應用程序等待新客戶端時服務器應用程序沒有被阻止。
但是,這個應用程序(甚至套接字)可以處理多個並發請求嗎?
如果客戶端 A 和 B 同時連接會發生什么?
如果客戶端 A 連接並且處理其請求需要 5 秒,如果客戶端 B 稍后連接,它是否必須等待客戶端 A 完成才能開始處理?
還是會同時處理客戶端 A 和客戶端 B 的請求?
我通過在套接字偵聽器代碼中的接收/發送數據之間放置 Thread.Sleep(n) 命令對此進行了一些測試。 然后我可以向套接字發送多個請求,它們似乎已被處理。 然而,套接字總是在同一個線程 id 上處理它們——這讓我相信它實際上並沒有同時發生。
特別是考慮到微軟的描述,這個應用程序在等待新連接時根本不會阻塞——這是否意味着它可以處理並發連接?
[2014 年更新]:自發布此答案以來,該示例似乎已被修改,如該線程中所述。 MSDN 示例現在可以正確處理多個傳入連接。 無論如何,這里描述的一般方法是正確的,也許它可以提供額外的說明。
在進行套接字通信時,基本上所有傳入連接都有一個偵聽器套接字,每個連接的客戶端都有多個處理程序sockets。
當您開始偵聽端口時,您會為傳入連接創建一個帶有回調方法的套接字(這是引用您提到的示例)。 這是該端口號的唯一偵聽器套接字:
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
此行告訴偵聽器在連接新客戶端時調用AcceptCallback
方法(新連接回調)。 該方法應該快速完成其工作,因為它會阻止其他傳入連接。
這也是為什么AcceptCallback
必須立即使用自己的后台數據回調方法( ReadCallback
)創建一個專用的“處理程序”套接字:
// inside AcceptCallback, we switch to the handler socket for communication
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state); // fired on a background thread
從那一刻起,只要新連接的客戶端收到一些數據,就會調用ReadCallback
方法。
另外,在返回之前, AcceptCallback
需要再次調用listener.BeginAccept
,以繼續監聽新的傳入連接:
// this is the same server socket we opened previously, which will now
// continue waiting for other client connections: it doesn't care about
// the actual data transmission between individual clients
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
這部分在 MSDN 示例中被省略,意味着它只能接收一個連接。
一旦從客戶端獲得數據包,就會調用ReadCallback
方法。 所以,在這個數據回調方法中,你需要讀取並處理接收到的數據,然后再次調用相同的BeginReceive
方法(同樣,使用ReadCallback
作為它的數據回調方法)。
[編輯]
MSDN 示例的問題在於它只允許連接單個客戶端( listener.BeginAccept
僅調用一次)。 要允許多個並發連接,您需要使用handler.BeginReceive
創建一個接收套接字,然后調用listener.BeginAccept
開始監聽新客戶端。
每個套接字都會有一個與之關聯的監聽隊列。 這將有待處理/部分接受的傳入連接。 掛起連接的最大數量可以在listen() API 中以編程方式定義,在本例中只是“listener.Listen(100)”。 在這里設置為 100,套接字“偵聽器”在偵聽隊列中可以有 150 (=2*100/2) 個掛起的連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.