C# .NET Socket connection issue - Only one usage of each socket address is normally permitted

15,797

Solution 1

Yes, your server socket is likely in the TIME_WAIT state.

You can access the underlying ServerSocket and then use SetSocketOption and specify ReuseAddress.

Solution 2

I'm going to guess here that ClientConnection is your DLL, because I don't see that already included in the CF.

You don't really need that, though, if you declare MethodInvoker.

public delegate void MethodInvoker(); // required

To make your code really slick, you should also create your very own EventArgs class:

public class WmTcpEventArgs : EventArgs {

  private string data;

  public WmTcpEventArgs(string text) {
    data = text;
  }

  public string Data { get { return data; } }

}

Very simple. With this new WmTcpEventArgs class and, you should be all set to receive your data that could post to something like a TextBox control:

private void NetworkResponder(object sender, WmTcpEventArgs e) {
  textBox1.Text = e.Data;
}

Instead of coding a while(true) in your code, I prefer to include a little Boolean variable

private bool abortListener;

The code would look something like this:

public void Listen() {
  listener.Start();
  while (!abortListener) {
    try {
      using (var client = listener.AcceptTcpClient()) {
        int MAX = client.ReceiveBufferSize;
        var now = DateTime.Now;
        using (var stream = client.GetStream()) {
          Byte[] buffer = new Byte[MAX];
          int len = stream.Read(buffer, 0, MAX);
          if (0 < len) {
            string data = Encoding.UTF8.GetString(buffer, 0, len);
            MethodInvoker method = delegate { NetworkResponder(this, new WmTcpEventArgs(data)); };
            abortListener = ((form1 == null) || form1.IsDisposed);
            if (!abortListener) {
              form1.Invoke(method);
            }
          }
        }
      }
    } catch (Exception err) {
      Debug.WriteLine(err.Message);
    } finally {
      listener.Stop();
    }
  }
}

Notice you are still catching your Exceptions, but you also stop the TcpListener.

Share:
15,797
Astronaut
Author by

Astronaut

merge keep

Updated on July 06, 2022

Comments

  • Astronaut
    Astronaut almost 2 years

    I am having the following issue:

    Once I close my WM6 application and then try to start it again i get this error: Only one usage of each socket address (protocol/network address/port) is normally permitted at System.Net.Sockets.Socket.Bind(EndPoint localEP) at System.Net.Sockets.Socket.TcpListener.Start() ...

    I think this is due to the time interval for the connection to timeout, so I would like to close all open conections and force it to create a new connection, is this the correct way to proceed or is there a different way to handle this?

    Here is the code used to start listening:

    /// <summary>
    /// Listens Asynchronously to Clients, creates a recieveMessageHandler to process the read.
    /// 
    /// Check WIKI, TODOS
    /// </summary>
    /// <returns></returns>
    public void Listen()
    {
        myTcpListener.Start();
    
        while (true)
        {
            //blocks until a client has connected to the server
            try
            {
                TcpClient myTcpClient = myTcpListener.AcceptTcpClient();
                DateTime now = DateTime.Now;
                //Test if it's necessary to create a client
                ClientConnection client = new ClientConnection(myTcpClient, new byte[myTcpClient.ReceiveBufferSize]);
    
                // Capture the specific client and pass it to the receive handler
                client.NetworkStream.BeginRead(client.Data, 0, myTcpClient.ReceiveBufferSize, r => receiveMessageHandler(r, client), null);
            }
            catch (Exception excp)
            {
                Debug.WriteLine(excp.ToString());
            }
        }
    }
    
  • Astronaut
    Astronaut about 11 years
    Ill give that a try... I find that Compact Framework has some quirks with sockets, so Ill try and see if that is available.
  • Astronaut
    Astronaut about 11 years
    So after the creation of the listner I should do: myTcpListener.Server.SetSocketOption(SocketOptionLevel.Socke‌​t, SocketOptionName.ReuseAddress, true);