Search code examples
c#.net-coretcpclient

The operation is not allowed on non-connected sockets


I'm new to async programming which I think might be my problem here but checking out other answers, I'm not sure I find one that fits my situation.

I'm attemping to use the TcpClient to connect to a server and port and get the stream from that but I get an error of:

The operation is not allowed on non-connected sockets

I can only assume this is because of the async connect

Another confusion point for me is that it seems TcpClient has a Connect not just ConnectAsync TcpClient Connect method but it won't build with the error that TcpClient does not contain a definition for Connect.

There's also this documentation I tried to use and it seems GetStream is the answer but I'm not sure I'm implementing it correctly. .NET Core TcpClient

using (var irc = new TcpClient())
{
    irc.ConnectAsync(_server, _port);

    using (var stream = irc.GetStream())
    using (var reader = new StreamReader(stream))
    using (var writer = new StreamWriter(stream))
    {
      // Rest of code
    }
}

Solution

  • The code doesn't await for the connection to finish. The problem isn't caused by ConnectAsync, its caused because GetStream is called before the client had a chance to connect

    Just change your code to :

    await irc.ConnectAsync(_server, _port);
    

    In order to use await you'll have to change the signature of the enclosing method to async Task or async Task<something> if it returns a result:

    async Task MyMethodAsync()
    {
        ...
        await irc.ConnectAsync(_server, _port);
        ...
    }
    

    or

    async Task<string> MyMethodAsync()
    {
        ...
        await irc.ConnectAsync(_server, _port);
        ...
        return result;
    }
    

    DON'T try to block any asynchronous calls with .Wait() or .Result. This will block the original thread and probably result in deadlocks. There's no point in calling an asynchronous method if you end up blocking on it after all.

    Don't use the async void signature either. This is reserved only for asynchronous event handlers. Methods that return no result should have an async Task signature