0

I'm trying to upgrade from UDP to TCP, but I am completely lost. :(

This is my Server code (not too long).

    private readonly TcpListener _tcpListener;

    public TCP(IPEndPoint endPoint)
    {
        try
        {
            _tcpListener = new TcpListener(endPoint);
            _tcpListener.Start();

            AcceptTcpClient();
            AcceptSocket();


            TestClient test = new TestClient();
            test.Connect();
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: " + e);
        }
        finally
        {
            _tcpListener.Stop();
        }
    }

    private void AcceptSocket()
    {
        _tcpListener.BeginAcceptSocket(AcceptIncomingSocket, _tcpListener);
    }
    private void AcceptTcpClient()
    {
        _tcpListener.BeginAcceptTcpClient(AcceptConnection, _tcpListener);
    }
    private void AcceptIncomingSocket(IAsyncResult ar)
    {
        try
        {
            var clientSocket = _tcpListener.EndAcceptSocket(ar);

            Console.WriteLine("Socket accepted: " + clientSocket.Connected);
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: " + e);
        }
    }

    private void AcceptConnection(IAsyncResult ar)
    {
        try
        {
            if (ar != null)
            {
                TcpClient client = _tcpListener?.EndAcceptTcpClient(ar);

                Console.WriteLine("Connected. " + (client != null && client.Connected));
                Console.ReadLine();
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: " + e);
        }
        catch (ObjectDisposedException e)
        {
            Console.WriteLine("Disposed: " + e);
        }
    }

and here is my client code:

            client = new TcpClient();

            client.Connect("127.0.0.1", 2500);

            if (client.Connected)
            {
                Console.WriteLine("TestClient_Connected");
                Console.ReadLine();
            }

            NetworkStream stream = client.GetStream();

            byte[] toSend = System.Text.Encoding.ASCII.GetBytes("HELLO THERE");

            stream.Write(toSend, 0 , toSend.Length);

            byte[] toSend2 = System.Text.Encoding.ASCII.GetBytes("HELLO 2");

            stream.Write(toSend2, 0, toSend2.Length);


            Console.ReadLine();
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }

The problem is, when I create the client instance, my server won't call the AcceptConnection, but instead it calls AcceptIncomingSocket. After that when the client's second write comes in the function AcceptConnection is called, and throws this exception: (Whole console output, because of the debug messages)

TestClient_Connected
Socket accepted: True


Disposed: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
   at System.Net.Sockets.Socket.EndAccept(Byte[]& buffer, Int32& bytesTransferred, IAsyncResult asyncResult)
   at System.Net.Sockets.TcpListener.EndAcceptTcpClient(IAsyncResult asyncResult)
   at ChallengersDeepDedicated.Server.TCP.AcceptConnection(IAsyncResult ar) ```
Aldabeth
  • 63
  • 5
  • You should go with either BeginAcceptSocket or BeginAcceptTcpClient. When a connection request is made, you either accept it as socket or tcp client (whichever you are familiar with), but not both. I would recommend the TcpClient because you can also access the Socket instance it wraps. – Oguz Ozgul May 03 '20 at 17:32
  • Thank you Oguz, you were right! :) – Aldabeth May 03 '20 at 18:33

1 Answers1

0

I would recommend you to take a look at the Microsoft docs, there are good examples of asynchronous socket client and server:

Server: https://learn.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example

Client: https://learn.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example

Writing a socket client-server program could be tricky. For having a good implementation I would recommend you dive into details and learn how it works and how properly use it.

I'm sure going over the docs would be useful and will help you understand the concept of sockets.

After reading that, check the new high-performance System.IO.Pipelines library that manages the buffer for you and make your life easier:

https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net//#comment-5471

y-me
  • 277
  • 4
  • 13