| 模式 | Accept 迴圈 | Read 迴圈 | 能力 |
|---|---|---|---|
| 1 | 無 | 無 | 單一用戶端、單一請求 |
| 2 | 有 | 有 (同層) | 多用戶端、各一請求 (循序處理) |
| 3 | 無 | 有 | 單一用戶端、多請求 |
| 4 | 巢狀雙層 | 內層 | 多用戶端、多請求 (需多執行緒) |
do {
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Client Connected! ...");
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[BufferSize];
int bytesRead = stream.Read(buffer, 0, BufferSize);
string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received: {0}", msg);
} while (true);
TcpClient client = listener.AcceptTcpClient(); // 單次 Accept
NetworkStream stream = client.GetStream();
do {
byte[] buffer = new byte[BufferSize];
int bytesRead = stream.Read(buffer, 0, BufferSize);
string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received: {0}", msg);
} while (true);
外層 Accept 迴圈在主執行緒,內層 Read 迴圈必須委派給新執行緒 (或 ThreadPool/Task),否則主執行緒卡在內層 Read 無法接受新連線。這是生產級伺服器的基本架構。
NetworkStream stream = client.GetStream();
ConsoleKey key;
Console.WriteLine("Menu: S - Send, X - Exit");
do {
key = Console.ReadKey(true).Key;
if (key == ConsoleKey.S) {
Console.Write("Input the message: ");
string msg = Console.ReadLine();
byte[] buffer = Encoding.Unicode.GetBytes(msg);
stream.Write(buffer, 0, buffer.Length);
Console.WriteLine("Sent: {0}", msg);
}
} while (key != ConsoleKey.X);