[英]StreamWriter ReadLine method hangs program
我正在嘗試在C#中使用一些基本的多線程。 我沒有找到明確的教程,因此請遵循以下標准代碼:
class Program
{
private static TcpListener listener;
private static List<TcpClient> clients;
static void Main(string[] args)
{
listener = new TcpListener(IPAddress.Any, 1337);
clients = new List<TcpClient>();
StartListening();
Console.WriteLine("Accepting clients..");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
static async void StartListening()
{
listener.Start();
while (true)
{
clients.Add(await listener.AcceptTcpClientAsync().ConfigureAwait(false));
Console.WriteLine("Client connected!");
HandleClient(clients[clients.Count - 1], clients.Count);
}
}
static async void HandleClient(TcpClient c, int number)
{
Console.WriteLine($"Getting client #{number}'s handshake..");
var ns = c.GetStream();
var sr = new StreamReader(ns);
var handshake = sr.ReadLine();
Console.WriteLine("Client {0}'s handshake: {1}", number, handshake);
}
}
是的,因此我要在服務器程序中實現的目標是:
1. Accepting client
2. Receiving handshake, print it to console
3. Add to the clients list
接受客戶端的部分起作用,但是該程序僅在HandleClient()
的第一行之后停止。 我嘗試過等待荒謬的時間(1000毫秒),即使那樣它什么也沒收到,也不會拋出異常(即保持連接狀態)。 我在這里做錯了什么?
如果需要,客戶端代碼在這里 !
您的客戶端代碼在這里已損壞-您永遠不會刷新它:
var sw = new StreamWriter(ns);
Thread.Sleep(1000);
sw.WriteLine(handshake);
不需要Thread.Sleep
調用,但如果希望將數據立即立即實際發送到網絡層,則應刷新StreamWriter
:
sw.Flush();
盡管(如Stephen Cleary所指出的那樣)這並不意味着它一定要立即發送,但可以合理地期望它在刷新后“合理地盡快”發送。
我正在嘗試在C#中使用一些基本的多線程。
我總是對嘗試通過編寫裸機TCP / IP服務器來學習並發性的開發人員感到驚訝(以前他們從未對TCP / IP進行過編程)。 並發和TCP / IP是兩個非常困難的主題; 試圖同時學習它們幾乎肯定會以災難告終。 這種方法如此普遍真是奇怪。
如果您想學習異步,我推薦我的async
介紹和關於最佳實踐的文章 (除其他外,您將學習“避免async void
”原則)。
如果您想學習TCP / IP,我推薦我的TCP / IP .NET FAQ博客系列 。 但是,幾乎不需要編寫TCP / IP代碼,並且由於您可以更改客戶端和服務器,因此我強烈建議改用SignalR。
我懷疑您實際上是想學習async
,而TCP / IP才剛剛開始。 因此,請刪除較難的主題(TCP / IP),並將async
與更簡單的通信(例如WebAPI或SignalR)一起使用。
(就您所看到的實際問題而言,它確實是由緩沖引起的,但是需要注意的是,刷新緩沖區不會導致數據立即通過網絡發送;它只會立即發送到網絡層 。適當的解決方案將需要消息框架。)
正如喬恩·斯基特(Jon Skeet)所提到的,要確保內容不僅僅位於緩沖區中,您應該刷新它。
您的客戶應如下所示:
var sw = new StreamWriter(ns);
Thread.Sleep(1000); // let the server catch up
sw.WriteLine(handshake);
sw.Flush();
Console.WriteLine("Staying connected.. Press ESCAPE to exit.");
編輯:忘記提及... Thread.Sleep(1000);
在那里...您可以安全地將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.