2011-04-08 26 views
2

卡住我有一個TCP隧道在C#。我需要打開和關閉服務器和客戶端之間的應用程序隧道。我正在使用這個關閉數據連接來測試另一個應用程序。我必須使用特定的端口。港TIME_WAIT

在第二,第三,第n個視我等多久才能重新連接時,我收到一個10048錯誤代碼 - 「地址已在使用」結合我的插座時。當關閉套接字,我不執行ShutDown.Both並清理出港口的希望關閉,但是當我在命令提示符下做了netstat的我仍然覺得在TIME_WAIT舉行的端口。我也設置插座不要流連忘返。最後我試圖做一個循環來檢查端口的狀態,但它在一個有點無盡的循環結束。我在想這是4分鐘的TIME_WAIT規則。

我有一個函數來顯示一個nestat查詢,我發現,當我運行它,並檢查,直到端口從ESTABLISHED進入TIME_WAIT,我可以綁定,但是當我使用這個查詢中的相同數據綁定循環時的狀態到達TIME_WAIT,我得到了10048有沒有被我按一下按鈕允許在一段短暫的瞬間,讓我綁定?有沒有TIME_WAIT之間的狀態,並建立我打的循環,而不是當我點擊按鈕做呢?我讀TIME_WAIT應該阻止我完全綁定,但這似乎不是真的。有人可以解釋這一點嗎?

我向你道歉代碼愛好者。不認爲這會改變任何事情。我只需要更好地瞭解端口狀態。

public bool CheckAvailablePorts() 
    { 
     int temp=0; 
     bool availPort= true; 
     m_config = new AppConfig(); 
     if (!m_config.initialize()) 
     { 
      System.Diagnostics.Debug.WriteLine("Error loading configuration file. Exiting..."); 
      return false; 
     } 
     else 
     { 

//checking through all the ports that have been set to connect on 

      foreach (ProxyConfig cfg in m_config.m_proxyConfigs) 
      { 
       availPort = true; 
       temp = cfg.localEP.Port; 
       DataView dv = FindEstablishedSockets();//returns netstat query 
       foreach (DataRowView rowView in dv) 
       { 
        DataRow row = rowView.Row; 

        if ((Convert.ToInt32(row["Local Port"].ToString()) == temp) && (row["Status"].ToString().Equals("Established"))) 
        { 
         System.Diagnostics.Debug.WriteLine("Port: " + temp + " is still locked"); 
         availPort = false; 
         break; 
        } 
       } 
      } 
      return availPort; 
     } 
    } 

//snippet out of a bigger function which checks for availability and then sleeps if false and runs again 

      bool temp = false; 
      while (!temp) 
      { 
       temp = monitor.CheckAvailablePorts(); 
       System.Threading.Thread.Sleep(2000); 
      } 
      System.Threading.Thread.Sleep(3000); 
      monitor.startApplication(); //starts all the binding 
+0

在Windows上,當你釋放端口,它停留在TIME_WAIT一些配置的超時。這裏有一個註冊表設置,'HKLM/System/CurrentControlSet/Services/Tcpip/Parameters/TCPTimedWaitDelay' – 2011-04-08 13:32:36

+0

根據誰關閉連接,Time_wait可能發生在服務器或客戶端,可能讓客戶端在意這一點? – 2011-04-08 13:37:35

+0

http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/建議對TCP進行一些更改以解決此問題。我不認爲他的想法是成功的,但有關於這個問題的一些細節。 – 2011-04-08 13:44:47

回答

0

你需要更具體一些,因爲很難知道你在做什麼。較短的文本和代碼示例會有所幫助。

我需要打開和關閉連接,然後再重新打開它們

這不應該是一個問題,如果它在客戶端。如果是服務器端,請解釋原因。

服務器上的配置文件正在尋找一個特定的端口,所以當我重新我需要相同的端口打開再次

你是什麼意思?如果你的意思是監聽端口:你不應該關閉監聽端口。如果你不想接受多個插座,根本就沒有再次直到客戶端套接字已斷開了的呼叫Accept

+0

你是說殺死接受EndAccept的套接字嗎? – VengefulSakhmet 2011-04-08 16:22:08

+0

相同的套接字應該調用'BeginAccept'和'EndAccept' =>監聽套接字。該套接字應該在應用程序的生命週期中生存。當連接關閉時,應由客戶端套接字「EndAccept」返回的套接字關閉。 – jgauffin 2011-04-08 18:38:17

0

我讀TIME_WAIT應該阻止我完全綁定,但這似乎不是真的。

有可以使用,讓你綁定一個本地端口在TIME_WAIT一個選項。這是非常有用的,以確保你沒有重新啓動前殺死了服務器後要等待4分鐘。

int flag = 1; 
sockfd = socket(...); 
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); 
bind(...); 
-2

之前關閉套接字,請您務必閱讀其對端發送數據,否則會留在TIME_WAIT,以確保新的插座將無法讀取用於先前的數據(封閉的)。你也可以嘗試套接字沒有延續的選項。

詳情:http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx

+0

實際上並非如此;好吧,它是混亂的。有關詳細信息,請參見http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-implications-for-protocols-and-scalable-servers.html。 – 2012-02-02 09:05:13

+0

這是完全不真實的。待處理的數據與TIME_WAIT無關。當您關閉套接字時,它全部被丟棄,並且所有到達的數據都會導致發生復位。 – EJP 2015-08-20 00:29:14

+0

哇,那是我的一個真正的舊帖子......復活;) 我站好了! – mBardos 2015-09-08 18:14:02