2013-02-01 70 views
27

我已經做了大量的搜索,但沒有多少運氣與我的問題。我是新來的網絡編程和試圖學習,我試圖建立一個簡單的服務器&客戶端通信(下面的在線教程位於這裏 - >http://tech.pro/tutorial/704/csharp-tutorial-simple-threaded-tcp-server如何解決錯誤「每個套接字地址(協議/網絡地址/端口)通常只允許使用一次」?

我遇到的問題是,我保持獲取異常「嘗試啓動服務器上的TcpListener時,通常只允許每個套接字地址(協議/網絡地址/端口)的一個用法。

我試過禁用我的防火牆,更改要使用的端口,移動變量但無濟於事(客戶端正常工作,但顯然無法找到服務器,因爲我無法啓動它)。

我見過描述使用Socket.Poll()的解決方案,但由於我只使用TcpListener對象,我不知道如何使用Poll函數。

我的代碼:

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

在我的主要方法:

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

任何幫助,非常感激!

+0

注意''mingw-w64'你需要'closesocket()'而不是'close()'來釋放端口。 – Jeroen

回答

23

ListenForClients被調用兩次(在兩個不同的線程上) - 一次來自構造函數,一次來自Main中的顯式方法調用。當TcpListener的兩個實例嘗試偵聽同一個端口時,會出現該錯誤。

+2

+1這也解釋了爲什麼當您更改端口號時仍然存在錯誤 –

+1

非常感謝!有時候很容易忽略這種愚蠢的事情! :D <3 –

8

您正在調試兩次或更多次。所以應用程序可能一次運行更多。那麼只有這個問題會發生。您應該使用task-manager關閉所有調試應用程序,然後再次調試。

相關問題