2017-01-18 154 views
0

我有一個帶有兩個按鈕的窗體,首先開始偵聽套接字,並顯示帶有地址的消息框,從該地址發送地址消息。第二個按鈕用於發送消息,以解決當我按下監聽按鈕時正在監聽的問題。我試圖綁定發送的套接字。例如,我想從端口50000發送它。我使用的是Bind方法,但它只在第一時間工作,而不是異常變成,該地址通常只能使用一次,而且我需要重新打開表單。我怎麼解決這個問題 ?這裏是我的代碼發送:綁定發送套接字

private void button2_Click(object sender, EventArgs e) 
    { 
     string local_host = System.Net.Dns.GetHostName(); 
     string local_ip_address = Dns.GetHostByName(local_host).AddressList[0].ToString(); 
     IPEndPoint send_point = new IPEndPoint(IPAddress.Parse(local_ip_address), 50000); 

     Socket send_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     IPEndPoint connected_point = new IPEndPoint(IPAddress.Parse(textBoxIPListen.Text), 
                Convert.ToInt32(textBoxPortListen.Text)); 
     try 
     { 
      send_socket.Bind(send_point); 
      send_socket.Connect(connected_point); 
      byte[] data = Encoding.Unicode.GetBytes("TestTest"); 
      send_socket.Send(data); 
      send_socket.Close(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    } 

回答

1

Bind()Listen()組合用於在指定的連接綁定socket。基本上你可以用Bind()套接字只聽特定的端口和地址,但要連接到另一個遠端,你應該使用簡單的Connect()方法。

因爲它在文件中說:https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind(v=vs.110).aspx

必須調用綁定後,才能調用Listen方法。除非需要使用特定的本地端點,否則在使用Connect方法之前不需要調用Bind。

這對您的情況意味着什麼?這意味着你試圖綁定來自(假設)127.0.0.1:5000的數據包來通過127.0.0.1:4990。你當然可以這麼做,但是你必須記住,只要你想「重新綁定」,就要從本地端點解除綁定這個套接字。

如果這是您的預期行爲,那麼在關閉它之後,我可以建議使用Dispose()套接字。這將從套接字中解除本地終點。例如:

send_socket.Close(); 
using (send_socket){ } 

編輯:

如果它只能在第一時間,我會建議using插座:

try 
    { 
     using(send_socket) { 
      send_socket.Bind(send_point); 
      send_socket.Connect(connected_point); 
      byte[] data = Encoding.Unicode.GetBytes("TestTest"); 
      send_socket.Send(data); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 

或者你可以讓你的插座實例綁定使成員場Socket send_socket作爲您的Form類的成員,並帶有send_socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, true);選項集。

+0

Dziekuje!但問題是,老闆想要我從指定的地址發送消息。如果我使用的只是連接方式,這是完全發送,但系統自動選擇端口,這不是我的老闆想要的:/當我在連接之前使用綁定,它的工作原理,我可以使用我自己的地址,但它只是第一次工作,而不是成爲例外。 – Ramon

+0

我嘗試過使用'(send_socket)',但不幸的是它沒有幫助:/仍然有相同的異常。 我會嘗試第二個建議。因此,完整的代碼將如下所示: 'try { send_socket.Bind(send_point); send_socket.Connect(connected_point); byte [] data = Encoding.Unicode.GetBytes(「TestTest」);send_socket。發送(數據); }' – Ramon

+0

奇怪,但第二個建議並沒有幫助。我試圖在任何地方嘗試,但沒有奏效。 – Ramon

1

而不是在Try部分中調用send_socket.Close()我寧願在finally塊中調用它,以確保即使引發異常,也關閉套接字。否則,如果出現任何問題,您可能會保持套接字打開。

try 
    { 
     send_socket.Bind(send_point); 
     send_socket.Connect(connected_point); 
     byte[] data = Encoding.Unicode.GetBytes("TestTest"); 
     send_socket.Send(data); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 
    finally 
    { 
     send_socket.Close(); 
    } 
+0

感謝您的建議!你說得對,無論如何都要好好關閉它。但不幸的是,無論如何,我只能第一次發送我的消息,而不是異常變成:/ – Ramon