2015-12-06 86 views
2

我在使用TcpClient和TcpListener時引發此異常時有點遺憾。它的工作原理是第一次,我然後再次運行它,我得到以下異常:TcpClient套接字 - 每個套接字地址的唯一用法例外

每個套接字地址(協議/網絡地址/端口)只有一個用法是正常允許127.0.0.1:8086

我檢查過以確保我關閉了任何打開的連接。我已經嘗試手動調用關閉TcpClient以及使用IDisposable使用模式,但仍然有同樣的問題。

下面的代碼,如果你複製粘貼在Visual Studio(前提是你已經添加以下using語句),它應該只是運行

using System; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading.Tasks; 

internal class Program 
{ 
    private static void tcpClientConnection() 
    { 
     Console.WriteLine("Ready"); 
     Console.ReadKey(); 

     IPAddress address = IPAddress.Parse("127.0.0.1"); 

     using (TcpClient client = new TcpClient(new IPEndPoint(address, 8087))) 
     { 
      client.Connect(new IPEndPoint(address, 8086)); 

      using (NetworkStream ns = client.GetStream()) 
      { 
       ns.Write(System.Text.Encoding.ASCII.GetBytes("Hello"), 0, "Hello".Length); 
       ns.Flush(); 
      } 

      Console.WriteLine("Closing client"); 
     } 
    } 

    internal static void Main(string[] args) 
    { 
     IPAddress address = IPAddress.Parse("127.0.0.1"); 

     TcpListener server = new TcpListener(new IPEndPoint(address, 8086)); 
     server.Start(); 

     using (Task task2 = new Task(tcpClientConnection)) 
     { 
      task2.Start(); 

      using (TcpClient client = server.AcceptTcpClient()) 
      { 
       using (NetworkStream ns = client.GetStream()) 
       { 
        using (MemoryStream ms = new MemoryStream()) 
        { 
         ns.CopyTo(ms); 
         byte[] data = ms.ToArray(); 

         Console.WriteLine(System.Text.Encoding.ASCII.GetString(data)); 
        } 
       } 
      } 

      Console.WriteLine("Server stop"); 
      Console.ReadKey(); 

      server.Stop(); 
     } 

     Console.WriteLine("END"); 
     Console.ReadKey(); 

    } 
} 

請注意,我們查看了在提供的解決方案類似的問題,但一直沒有能夠看到什麼問題...

+2

對於TcpClient,不要指定本地端點。我認爲這解決了問題,你不應該這樣做,因爲它什麼都不做。 – usr

+0

非常棒的地方,那確實是馬上解決了問題,謝謝!我會詳細說明本地端點的具體含義。它不只是每次都使用同一個端口的套接字?如果所有連接都關閉了,是否應該繼續使用相同的地址和端口?只是想知道,謝謝 – redspidermkv

回答

1

對於TcpClient不指定本地端點。我認爲這解決了問題,你不應該這樣做,因爲它什麼都不做。 指定傳出連接的本地端點使操作系統選擇合適的可用值。通常,99.9%的程序正在這樣做。

如果所有的連接都關閉了,是不是應該繼續使用相同的地址和端口?

TCP有一些不直觀的行爲,導致連接在關閉後暫時停留一段時間。通過讓操作系統選擇一個新的端口來減輕問題。

您還可能想要查看Task的使用情況並選擇一些最佳做法:使用Task.Run並且不要處置。沒有用。

+0

謝謝,我會盡快接受。最後一個問題,如果你不介意,你知道我們可以強制連接關閉後的任何方式消失後? :) – redspidermkv

+1

使用4.0上的Task.Factory.StartNew。我不熟悉TCP連接問題。無論如何,在關閉連接之前,您應該在雙方都調用Shutdown(Both)。但我不認爲這解決了這個問題。我認爲你根本不需要解決它,通常沒有人需要解決它。這是一個罕見的問題。 – usr

相關問題