简体   繁体   中英

StreamWriter ReadLine method hangs program

I am trying to get some basic multi-threading working in C#. There's no clear tutorial that I've found so bear with my sub-par code:

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);
    }
}

Right, so what I'm trying to achieve in the server program is:

 1. Accepting client
 2. Receiving handshake, print it to console
 3. Add to the clients list

The accepting client part works, however the program just stops just after the first line of HandleClient() . I've tried waiting for absurd amounts of time (1000ms) and even then it just doesn't receive anything, nor does it throw an exception (ie it stays connected). What am I doing wrong here?

Client code is here if you need it!

Your client code is broken here - you're never flushing it:

var sw = new StreamWriter(ns);
Thread.Sleep(1000);
sw.WriteLine(handshake);

There's no need for the Thread.Sleep call, but you should flush the StreamWriter if you want the data to actually be sent to the network layer immediately:

sw.Flush();

While (as Stephen Cleary notes) this wouldn't mean it necessarily got sent immediately , it's reasonable to expect it to be sent "reasonably soon" after flushing.

I am trying to get some basic multi-threading working in C#.

I'm always amazed at devs who try to learn concurrency by writing a bare-metal TCP/IP server (when they've never programmed TCP/IP previously). Concurrency and TCP/IP are two extremely difficult topics; trying to learn them at the same time is almost certainly going to end in disaster. It's just really odd that this is such a common approach.

If you want to learn asynchrony, I recommend my async intro and article on best practices (where, among other things, you'll learn the principle "avoid async void ").

If you want to learn TCP/IP, I recommend my TCP/IP .NET FAQ blog series . However, writing TCP/IP code is almost never necessary , and since you can change both the client and server, I strongly recommend using SignalR instead.

I suspect that you actually want to learn async , and the TCP/IP is just getting in the way. So, drop the harder topic (TCP/IP) and use async with simpler communications such as WebAPI or SignalR.

(As far as the actual problem you saw, it is indeed caused by buffering, but it's important to note that flushing the buffer does not cause the data to be send over the network immediately; it is only sent to the networking layer immediately. A proper solution would need message framing.)

As Jon Skeet mentioned, to make sure the content is not just sitting in a buffer, you should Flush it.

Your client should look like so:

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.");

EDIT: Forgot to mention... That Thread.Sleep(1000); there... you can safely remove it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM