2017-01-18 155 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