2013-02-01 116 views
27

Zrobiłem dużo googlowania, ale nie miałem szczęścia w moich problemach. Jestem nowy w programowaniu sieciowym i próbuję się nauczyć. Próbowałem skonfigurować prostego klienta serwera, który komunikuje się (po tutorialu online tutaj ->http://tech.pro/tutorial/704/csharp-tutorial-simple-threaded-tcp-server)Jak naprawić błąd "Tylko jedno użycie każdego adresu gniazda (protokołu/adresu sieciowego/portu) jest normalnie dozwolone"?

Problem, który mam, polega na tym, że mam Uzyskiwanie wyjątku "Tylko jedno użycie każdego adresu gniazda (protokołu/adresu sieciowego/portu) jest zwykle dozwolone" podczas próby uruchomienia TcpListener na serwerze.

Próbowałem wyłączyć moją zaporę ogniową, zmieniając port do użycia, zmieniając zmienne, ale bez skutku (klient działa dobrze, ale oczywiście nie może znaleźć serwera, ponieważ nie mogę go uruchomić).

Widziałem rozwiązania opisujące użycie Socket.Poll(), ale ponieważ używam tylko obiektu TcpListener, nie mam pojęcia, jak korzystać z funkcji ankiety.

Mój kod:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net.Sockets; 
using System.Net; 
using System.Threading; 
using System.Text; 

namespace ServerTutorial { 
class Server { 
    private readonly Thread m_listenThread; 

    public Server() { 
     m_listenThread = new Thread(new ThreadStart(ListenForClients)); 
     m_listenThread.Start(); 
    } 

    public void ListenForClients() { 
     var listener = new TcpListener(IPAddress.Any, 3000); 
     listener.Start(); 

     while (true) { 
      //Blocks until a client has connected to the server 
      TcpClient client = listener.AcceptTcpClient(); 

      //Send a message to the client 
      var encoder = new ASCIIEncoding(); 
      NetworkStream clientStream = client.GetStream(); 
      byte[] buffer = encoder.GetBytes("Hello Client!"); 
      clientStream.Write(buffer, 0, buffer.Length); 
      clientStream.Flush(); 

      //Create a thread to handle communication with the connected client 
      var clientThread = new Thread(new ParameterizedThreadStart(HandleClient)); 
      clientThread.Start(client); 
     } 
    } 

    private void HandleClient(object clientObj) { //Param thread start can only accept object types, hence the cast 
     var client = (TcpClient) clientObj; 
     NetworkStream clientStream = client.GetStream(); 

     var message = new byte[4096]; 

     while (true) { 
      int bytesRead = 0; 

      try { 
       //Block until a client sends a message 
       bytesRead = clientStream.Read(message, 0, 4096); 
      } catch { 
       //A socket error has occurred 
       System.Diagnostics.Debug.WriteLine("A socket error has occured"); 
       break; 
      } 

      if (bytesRead == 0) { 
       //The client has disconnected from the server 
       System.Diagnostics.Debug.WriteLine("A client has disconnected from the server"); 
       client.Close(); 
       break; 
      } 

      //Message has been received 
      var encoder = new ASCIIEncoding(); 
      System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead)); 
     } 
    } 
} 
} 

W moim główne metody:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ServerTutorial { 
class Program { 
    static void Main(string[] args) { 
     var server = new Server(); 
     server.ListenForClients(); 
    } 
} 
} 

Każda pomoc jest niezwykle ceniona!

+0

Uwaga na 'mingw-w64' potrzebujesz' closesocket() ', a nie' close() ', aby zwolnić port. – Jeroen

Odpowiedz

23

ListenForClients jest wywoływane dwa razy (na dwóch różnych wątkach) - raz z konstruktora, raz z jawnego wywołania metody w Main. Kiedy dwa wystąpienia TcpListener próbują nasłuchiwać na tym samym porcie, pojawia się ten błąd.

+2

+1 Co również wyjaśnia, dlaczego nadal występował błąd podczas zmiany numeru portu –

+1

Dziękuję bardzo! Czasami tak łatwo przeoczyć takie głupie rzeczy! : D <3 –

8

Debugujesz dwa lub więcej razy. więc aplikacja może działać więcej naraz. Wtedy tylko ten problem wystąpi. Należy zamknąć wszystkie aplikacje do debugowania za pomocą menedżera zadań, a następnie ponownie przeprowadzić debugowanie.

Powiązane problemy