web-dev-qa-db-ja.com

同じソケットからデータを送受信する単純なUDPの例

何らかの理由で、同じソケットからデータを送受信するのに苦労しています。とにかくここに私のクライアントコードがあります:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep); 

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);  // Exception: An existing connection was forcibly closed by the remote Host

基本的に、udpパケットを送信するプロトコルを作成してから、応答を期待します。すべての要求のHTTPプロトコルと同様に、応答があります。このコードは、サーバーが異なる場合に機能しますコンピューター。ただし、サーバーとクライアントが同じコンピューター上にある場合があります。

サーバーは次のとおりです。

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
    var data = udpServer.Receive(ref groupEP);
    udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data          
}

編集

tcpを使用できない理由は、クライアントがNAT(ルーター)の背後にあることがあり、TCPよりもUDPホールパンチの方が簡単だからです。


解決:

ここでのmarkmnlの答えのおかげで私のコードです:

サーバ:

UdpClient udpServer = new UdpClient(11000);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000); 
    var data = udpServer.Receive(ref remoteEP); // listen on port 11000
    Console.Write("receive data from " + remoteEP.ToString());
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}

クライアントコード:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);

Console.Write("receive data from " + ep.ToString());

Console.Read();
39
Tono Nam

(UDP(User Datagram Protocol)の使用は配信、重複のチェック、輻輳制御を保証するものではなく、単に質問に答えることに気づいていると思います)。

サーバーでこの行:

var data = udpServer.Receive(ref groupEP);

groupEPをあなたが持っていたものからあなたが何かを受け取るアドレスに再割り当てします。

この行:

udpServer.Send(new byte[] { 1 }, 1); 

データの送信先を指定していないため機能しません。 (クライアントで機能するのは、connectを呼び出したため、sendは常に接続先のエンドポイントに送信されることを意味します。もちろん、多くのクライアントが存在する可能性があるため、サーバーでは必要ありません)。私は...するだろう:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
    var data = udpServer.Receive(ref remoteEP);
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // if data is received reply letting the client know that we got his data          
}

また、同じマシン上にサーバーとクライアントがある場合は、それらを異なるポートに配置する必要があります。

25
markmnl

私はこれを短くしようとします、私は this 数ヶ月前に私が構築しようとしたゲームのために、TCPのように振る舞うUDP「クライアントサーバー」接続を行います、あなたはこれを使用して(メッセージ)(メッセージ+オブジェクト)を送信できます。私はそれでいくつかのテストを行いましたが、うまく動作します。必要に応じて自由に変更してください。

2
Creţu Cosmin