96029


C#でUDP Clientを使って通信を行おうとしています。  
device Aに以下のようなポート設定でSendすると、レスポンスとしてlocalport=47808,
destport=57575で返ってきていたため、udpのRecieveできるのですが、device Bでは固定でlocalport=47808,
destport=47808で返ってきます。  
この場合、device Bからのレスポンスを受け取る方法はあるのでしょうか?

ともに送信は成功しているのですが、device Bからの受信のみ失敗(timeout)してしまいます。

送信 : host --->(57575)---(47808)---> device A  
受信 : host <\---(57575)---(47808)<\--- device A

送信 : host --->(57575)---(47808)---> device B  
受信 : host <\---(47808)---(47808)<\--- device B

[code]

    var localport = 57575;
    var destport = 47808;
    var destIpAddr = "192.168.0.1";
    
    using (var udp= new UdpClient(localport))
    {
      udp.Send(sendBytes, len, destIpAddr, destPort);
      System.Net.IPEndPoint endPoint = null;
      var recvBytes = udp.Receive(ref endPoint);
    }
    
[/code]


CC BY-SA 4.0
2023-08-23T00:59:24.887
96017
2023-08-24T15:18:38.130
12388
question
c# udp
UDP ClientでSend時の指定ポート以外でレスポンスを受け取ることはできるのか?


sayuri さんがコメントしてらっしゃいますが device A に対して 47808 ポートから送信したら 47808 に返してくれる気もします。  
そうでない場合は、どちらでも受信できるように作ることも出来ます。

[code]

    const int localPort1 = 57575;
    const int localPort2 = 47808;
    
    static byte[] SendRecv(string destIpAddr, int destPort, 
                            byte[] sendBytes, int len) {
        byte[] recvBytes;
        using (var udp1 = new UdpClient(localPort1))
        using (var udp2 = new UdpClient(localPort2)) {
            // Connect するかどうかは要件しだい
            udp1.Connect(destIpAddr, destPort);
            udp2.Connect(destIpAddr, destPort);
            var t1 = udp1.ReceiveAsync();
            var t2 = udp2.ReceiveAsync();
            udp1.Send(sendBytes, len);
            var index = Task.WaitAny(t1, t2);
            if (index == 0) {
                Console.WriteLine($"{localPort1} から受信しました。");
                recvBytes = t1.Result.Buffer;
                CancelIo(udp2, t2);
            } else {
                Console.WriteLine($"{localPort2} から受信しました。");
                recvBytes = t2.Result.Buffer;
                CancelIo(udp1, t1);
            }
        }
        return recvBytes;
    }
    
    // 非同期 IO のキャンセル
    static void CancelIo(UdpClient udp, Task task) {
        CancelIo(udp.Client.Handle);
        try {
            task.Wait();
        } catch (AggregateException ex) 
             when (ex.InnerException is SocketException) {
            var port = ((IPEndPoint)udp.Client.LocalEndPoint).Port;
            Console.WriteLine($"{port} の受信をキャンセルしました。");
        }
    }
    
    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CancelIo(IntPtr hFile);
    
[/code]


CC BY-SA 4.0
2023-08-24T00:05:27.073
96029
2023-08-24T00:05:27.073
50741
96017
answer


> 諸事情がありlocalport=47808は使えない環境なのです

そうであれば

> 受信 : host <\---(47808)---(47808)<\--- device B

の受信は諦めてください。47808にbindしない限り、47808宛のメッセージを受信することはできません。


CC BY-SA 4.0
2023-08-24T15:18:38.130
96036
2023-08-24T15:18:38.130
4236
96017
answer