2013-03-13 21 views
5

Tôi gặp vấn đề sau:C kết nối # .NET Ổ cắm vấn đề - Chỉ có một cách sử dụng của mỗi địa chỉ socket thường được phép

Khi tôi đóng ứng dụng WM6 của tôi và sau đó cố gắng để bắt đầu nó một lần nữa tôi nhận được lỗi này: Chỉ sử dụng một địa chỉ của từng địa chỉ cổng (giao thức/địa chỉ mạng/cổng) tại System.Net.Sockets.Socket.Bind (EndPoint localEP) tại System.Net.Sockets.Socket.TcpListener.Start() ...

Tôi nghĩ điều này là do khoảng thời gian cho kết nối hết thời gian chờ, vì vậy tôi sẽ muốn đóng tất cả các phần mở và buộc nó tạo một kết nối mới, đây có phải là cách chính xác để tiến hành hoặc có cách nào khác để xử lý việc này không?

Đây là đoạn mã sử dụng để bắt đầu nghe:

/// <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

Đóng myTcpListener khi tắt máy. –

+0

Tôi làm, tuy nhiên tôi đang gọi một số Dll mà đôi khi sụp đổ các ứng dụng và mã tắt máy không được gọi. – Astronaut

+0

Bạn cần xử lý tốt hơn lỗi đó. Bởi chỉ cần rơi ra và rời khỏi tài nguyên không được quản lý của bạn nằm xung quanh, bạn nhận được lỗi này. Mặc dù CLR xử lý quản lý bộ nhớ cho bạn đối với các đối tượng được quản lý, bạn cần thực hiện nó cho các đối tượng không được quản lý, chẳng hạn như các kết nối tệp và mạng. –

Trả lời

4

Vâng, ổ cắm máy chủ của bạn có thể ở trong trạng thái TIME_WAIT.

Bạn có thể truy cập vào số ServerSocket cơ bản và sau đó sử dụng SetSocketOption và chỉ định ReuseAddress.

+0

Hãy thử một lần ...Tôi thấy rằng Compact Framework có một số quirks với ổ cắm, do đó, Ill thử và xem nếu đó là có sẵn. – Astronaut

+3

Vì vậy, sau khi tạo ra các listner tôi nên làm: myTcpListener.Server.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); – Astronaut

2

Tôi sẽ đoán ở đây rằng ClientConnection là tệp DLL của bạn, bởi vì tôi không thấy rằng đã được bao gồm trong CF.

Bạn không thực sự cần điều đó, tuy nhiên, nếu bạn khai báo MethodInvoker.

public delegate void MethodInvoker(); // required 

Để làm cho mã của bạn thực sự trơn tru, bạn cũng nên tạo đẳng cấp EventArgs rất riêng của bạn:

public class WmTcpEventArgs : EventArgs { 

    private string data; 

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

    public string Data { get { return data; } } 

} 

Rất đơn giản. Với điều này mới WmTcpEventArgs lớp, và bạn sẽ có tất cả các thiết lập để nhận được dữ liệu của bạn có thể gửi một cái gì đó giống như một TextBox kiểm soát:

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

Thay vì mã hóa một while(true) trong mã của bạn, tôi thích để bao gồm một chút boolean biến

private bool abortListener; 

mã này sẽ giống như thế này:

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

Lưu ý rằng bạn vẫn đang bắt ngoại lệ của mình, nhưng bạn cũng dừng lại TcpListener.

Các vấn đề liên quan