首页 文章

C#.NET套接字连接问题 - 通常只允许使用每个套接字地址

提问于
浏览
5

我有以下问题:

一旦我关闭我的WM6应用程序,然后尝试再次启动它我得到此错误: 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() ...

我认为这是由于连接超时的时间间隔,所以我想关闭所有打开的连接并强制它创建一个新的连接,这是正确的继续方式还是有不同的方法来处理这个?

以下是用于开始监听的代码:

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

2 回答

  • 1

    是的,您的服务器套接字可能处于TIME_WAIT状态 .

    您可以访问底层ServerSocket,然后使用SetSocketOption并指定ReuseAddress .

  • 4

    我在这里猜测 ClientConnection 是你的DLL,因为我没有看到已经包含在CF中 .

    但是,如果你声明MethodInvoker,你真的不需要那样做 .

    public delegate void MethodInvoker(); // required
    

    为了使你的代码非常流畅,你还应该创建自己的EventArgs类:

    public class WmTcpEventArgs : EventArgs {
    
      private string data;
    
      public WmTcpEventArgs(string text) {
        data = text;
      }
    
      public string Data { get { return data; } }
    
    }
    

    非常简单 . 有了这个新的 WmTcpEventArgs 类,您应该已经准备好接收可以发布到TextBox控件之类的数据:

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

    我没有在代码中编码 while(true) ,而是更喜欢包含一些布尔变量

    private bool abortListener;
    

    代码看起来像这样:

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

    请注意,您仍在捕捉例外情况,但您也会停止TcpListener .

相关问题