6

次の問題があります。

WM6 アプリケーションを閉じてからもう一度開始しようとすると、次のエラーが表示されます: System.Net.Sockets.Socket.Bind(EndPoint localEP) では、通常、各ソケット アドレス (プロトコル/ネットワーク アドレス/ポート) の使用は 1 つだけ許可されます。 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());
        }
    }
}
4

2 に答える 2

5

はい、サーバー ソケットが TIME_WAIT 状態になっている可能性があります。

基礎となるServerSocketにアクセスしてから、 SetSocketOption を使用してReuseAddressを指定できます。

于 2013-03-13T15:46:41.000 に答える
1

ClientConnectionCF に既に含まれているとは思えないので、これがあなたの DLL であると推測します。

ただし、 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;
}

コードにa をコーディングする代わりに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も停止していることに注意してください。

于 2013-03-14T16:39:37.590 に答える