2013-03-13 7 views
5

私は次の問題が午前許可されている各ソケットアドレス1つのだけ使用:私は私のWM6アプリケーションを終了し、再度起動してみたらC#.NETのソケット接続の問題 - 通常

は、私はこのエラーを取得: System.Net.Sockets.Socket.Bind(EndPoint localEP)で各ソケットアドレス(プロトコル/ネットワークアドレス/ポート)の1つの使用しか通常許可されていません 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()); 
     } 
    } 
} 
+0

シャットダウン時にmyTcpListenerを閉じます。 –

+0

私は、アプリケーションをクラッシュさせるDLLをいくつか呼び出していますが、シャットダウンコードは呼び出されません。 – Astronaut

+0

あなたはそのエラーをうまく処理する必要があります。あなたの管理されていないリソースを放置して放置するだけで、このエラーが発生します。 CLRは管理対象オブジェクトのメモリ管理を処理しますが、ファイルやネットワーク接続などの管理されていないオブジェクトに対して行う必要があります。 –

答えて

4

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

ServerSocketにアクセスし、SetSocketOptionを使用してReuseAddressと指定できます。

+0

悪いことを試してみてください...私は、Compact Frameworkにソケット付きのいくつかの欠点があることを知っています。だから、それが利用可能かどうか試してみてください。 – Astronaut

+3

したがって、リスナーを作成した後、私は次のことを行う必要があります。 myTcpListener.Server.SetSocketOption(SocketOptionLevel.Socket、SocketOptionName.ReuseAddress、true); – Astronaut

2

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コントロールのような何かに投稿することができ、あなたのデータを受信する必要があります:あなたのコードでwhile(true)をコーディングする代わりに

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

を、私は少しを含めることを好みますブール変数

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も停止してください。