2017-01-18 5 views
0

2つのボタンを持つフォームがあります。最初にListenソケットを開始し、アドレスメッセージが送信されたメッセージボックスを表示します。 2番目のボタンは、私がリッスンボタンを押しているときに聞いているアドレスにメッセージを送信するためのものです。私はsendedソケットをバインドしようとしています。たとえば、私はポート50000から送信したいと思います。私はBindメソッドを使用していますが、例外よりも最初のときに動作します。そのアドレスは通常1回だけ使用でき、フォームを再度開く必要があります。どうすればこの問題を解決できますか?ここに私のコードでは、送信するためです:バインド送信ソケット

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()は、指定された接続に上socketをバインドするListen()と組み合わせて使用​​されます。基本的にはBind()ソケットは特定のポートとアドレスでのみリッスンできますが、別のリモートに接続するには単純なConnect()メソッドを使用してください。

それはマニュアルには言われたとおり:https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind(v=vs.110).aspx

あなたが聞くメソッドを呼び出すことができます前に、あなたがバインドを呼び出す必要があります。特定のローカルエンドポイントを使用する必要がないかぎり、Connectメソッドを使用する前にBindを呼び出す必要はありません。

あなたのケースではどういう意味ですか?これは、127.0.0.1:5000から127.0.0.1:4990までのパケットをバインドしようとしていることを意味します。もちろんそうすることができますが、 "再バインド"したいときはいつでも、このソケットをローカルのエンドポイントからバインド解除することを忘れないでください。

これが意図した動作であれば、それを閉じた後にDispose()ソケットを提案できます。これにより、ソケットからローカルエンドポイントをアンバインドします。例:

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

EDIT:

それは初回のみが動作する場合、私は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()); 
    } 

それとも、メンバーフィールドを作るバインドあなたのソケットのインスタンスを維持することができますあなたのFormクラスのメンバーとしてSocket send_socketsend_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

奇妙ですが、2番目の助言も助けませんでした。私は試してみるとどこにでも置こうとしましたが、うまくいきませんでした。 – 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

関連する問題