Giannis Paraskevopoulos
Giannis Paraskevopoulos

Reputation: 18411

TCPListener blocks new connections

I have been asked to create a TCPListener console app to monitor incoming data in a specific port. I have searched a while and i have the following code which i run through LINQPad:

void Main()
{
    IPAddress ipAddress = IPAddress.Parse("127.0.0.1");

    Console.WriteLine("Starting TCP listener...");

    TcpListener listener = new TcpListener(ipAddress, 1005);
    try
    {

        listener.Start();
        while (true)
        {
            Socket client = listener.AcceptSocket();
            client.ReceiveTimeout.Dump();
            Console.WriteLine("Connection accepted.");

            var childSocketThread = new Thread(() =>
            {
                Byte[] bytes = new Byte[256];
                String data = null;
                int i;
                while((i = client.Receive(bytes))!=0 && data != "55AA") 
                {   
                    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                }
                Console.WriteLine("connection closing");
                client.Close();

                //throw new Exception();
            });
            childSocketThread.Start();
        }

        listener.Stop();
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.StackTrace);
        Console.ReadLine();
    }

}

This is actually a slightly modified code of a millions of examples in Google. My problem is that being in LINQPad i usually press the run button and then open a command prompt and telnet to 127.0.0.1 port 1005 and then i write something all good.

If i press the stop button in LINQPad and then press Run again, i end up with the following error:

Error: at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Bind(EndPoint localEP) at System.Net.Sockets.TcpListener.Start(Int32 backlog) at System.Net.Sockets.TcpListener.Start() at UserQuery.Main() in c:\Users\giannis\AppData\Local\Temp\LINQPad_jncifzyi\query_lgowqr.cs:line 40

Now, i understand that you may have only one client listening or using a specific port, but my issue is that 1st of all i want to play with LINQPad before going to the actual solution. I know that i could make the TCPListener variable a global and just handle it when exiting the program. But what if it crashes or something? Will i end up with not being able to connect to the port until log off log on?

Upvotes: 0

Views: 922

Answers (3)

Fedearne
Fedearne

Reputation: 7348

My problem was, that LINQPad keeps the process running after you cancel it.

Either use "Cancel All Threads and Reset" menu option (ctrl+shift+F5) or manually kill all "LINQPad.UserQuery.exe" processes in task manager.

The port should be free again.

Upvotes: 0

Nathan Surfus
Nathan Surfus

Reputation: 16

It is important to properly clean up your TcpListener, but you could add this before your Try statement: listener.ExclusiveAddressUse = false;

Reference: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.exclusiveaddressuse%28v=vs.110%29.aspx

Upvotes: 0

usr
usr

Reputation: 171178

Probably, the GC has not cleaned up the listener when you restart the program in LINQPad. In a real program all TCP ports are cleaned up when the process exits. Restart LINQPad and you'll find the port to be free again.

I don't see why using a Visual Studio project would be significantly more burdensome when it comes to quickly testing code. Just press F5. The dumping function is not there, though.

Upvotes: 1

Related Questions