2013-03-13 24 views
5

Aşağıdaki sorun yaşıyorum izin verilir her yuva adresi için yalnızca bir kullanıma: Ben WM6 uygulamasını kapatın ve yeniden başlatmayı deneyin kezC# .NET Soket bağlantısı sorunu - normalde

ben bu hatayı alıyorum: System.Net.Socket.Socket.Bind (EndPoint localEP) System.Net.Sockets.Socket.TcpListener.Start() adresinde yalnızca her bir soket adresinin (protokol/ağ adresi/bağlantı noktası) bir kullanımına izin verilir. ...

Bunun nedeni zaman aşımına bağlantı için zaman aralığı nedeniyle olduğunu düşünüyorum Tüm açık konileri kapatmak ve yeni bir bağlantı oluşturmak için zorlamak gibi, bu işlemin doğru yolu mu yoksa bu işlemin farklı bir yolu var mı?

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

Kapama sırasında myTcpListener'ı kapatın. –

+0

Ancak, bazen uygulamayı kilitleyen ve kapatma kodu çağrılmayan bazı Dlls'i arıyorum. – Astronaut

+0

Bu hatayı daha iyi kullanmanız gerekir. Sadece dışarıda bırakarak ve yönetilmeyen kaynaklarınızı etrafta bırakarak, bu hatayı alırsınız. CLR, yönetilen nesneler için sizin için bellek yönetimini ele alsa da, bunları dosya ve ağ bağlantıları gibi yönetilmeyen nesneler için yapmanız gerekir. –

cevap

4

Evet, sunucu soket TIME_WAIT durumunda muhtemeldir: Burada

dinleme başlatmak için kullanılan koddur.

Temeldeki ServerSocket'a erişebilir ve ardından SetSocketOption'u kullanabilir ve ReuseAddress'u belirtin.

+0

Bunu bir deneyin ...Kompakt Çerçeve'nin soketli bazı tuhaflıkları olduğunu buldum, bu yüzden mevcut olup olmadığını görmeye çalışıyorum. – Astronaut

+3

Listeyi oluşturduktan sonra yapmam gerekenler: myTcpListener.Server.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); – Astronaut

2

Burada tahmin ediyorum ki burada ClientConnection sizin DLL dosyanızdır, çünkü zaten CF'de yer aldığını görmüyorum.

MethodInvoker bildirirseniz, buna gerçekten ihtiyacınız yok.

public delegate void MethodInvoker(); // required 

ayrıca çok kendi EventArgs sınıf oluşturmak gerekir, kodunuz gerçekten kaygan hale getirmek için:

public class WmTcpEventArgs : EventArgs { 

    private string data; 

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

    public string Data { get { return data; } } 

} 

Çok basit. Bu yeni WmTcpEventArgs ile sınıf ve hazırsınız bir TextBox kontrolü gibi bir şeye sonrası olabilir sizin veri almaya olmalıdır: Kodunuzdaki bir while(true) kodlama yerine

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

, biraz dahil etmeyi tercih Boolean değişkeni

private bool abortListener; 

kodu şöyle görünecektir:

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

Hala Özel Durumlarınızı yakaladığınızı unutmayın, ancak TcpListener'u da durdurursunuz.