【问题标题】:C# UDP Packet Send & ReceiveC# UDP 数据包发送和接收
【发布时间】:2019-01-04 13:08:46
【问题描述】:

我正在尝试弄清楚如何使用 C# 作为客户端通过 UDP 协议发送和接收数据,并运行一个 JS 服务器来传输“响应”数据包以进行测试。

以下是我为测试而制作的 UDP 类,它只有 2 个线程:
一个从 UDP 读取接收到的数据,另一个线程用于发送数据。

using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;

using System.Threading;

namespace UDPTesting {

    class UDPHandler {

        private int receivePort, sendPort;
        private string serverIP;
        private IPEndPoint sendEndPoint, receiveEndPoint;

        public UDPHandler(string serverIP, int receivePort, int sendPort) {
            this.serverIP = serverIP;
            this.receivePort = receivePort;
            this.sendPort = sendPort;
            this.sendEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.sendPort);
            this.receiveEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.receivePort);
            this.readerUdpClient();
            this.senderUdpClient();
        }

        void readerUdpClient() {
            UdpClient readerClient = new UdpClient();
            IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 3000);
            readerClient.Client.Bind(localEndpoint);          //Tried both Connect and Bind
            //readerClient.Connect(this.receiveEndPoint);
            Thread t = new Thread(() => {
                Console.WriteLine("Awaiting data from server...");
                var remoteEP = new IPEndPoint(IPAddress.Any, 3000);
                byte[] bytesReceived = readerClient.Receive(ref remoteEP);
                //The above throws:     System.InvalidOperationException: 'You must call the Bind method before performing this operation'
                Console.WriteLine("Received data from " + remoteEP.ToString());
            });
            t.Start();
        }

        void senderUdpClient() {
            UdpClient senderClient = new UdpClient();
            senderClient.Connect(this.sendEndPoint);
            string sendString = "1;2;3";
            byte[] bytes = toBytes(sendString);
            Thread t = new Thread(() => {
                while (true) {
                    senderClient.Send(bytes, bytes.Length);
                    Thread.Sleep(1000);
                }
            });
            t.Start();
        }

        public byte[] toBytes(string text) {
            return Encoding.UTF8.GetBytes(text);
        }

        public string fromBytes(byte[] bytes) {
            return Encoding.UTF8.GetString(bytes);
        }

    }
}

另外,我的程序的“主要”是这样的:

using System;
using System.Threading;

namespace UDPTesting {

    class Program {

        static void Main(string[] args) {
            string serverIP = "46.101.102.243";
            int sendPort = 41234;
            int receivePort = 3000;
            UDPHandler handler = new UDPHandler(serverIP, receivePort, sendPort);
        }

    }

}

如何在客户端向服务器发送数据的同时读取服务器在客户端发送的响应?

我们单独测试过:

1) 从客户端发送 UDP 数据包 -> 服务器有效,因为我可以看到服务器接收到数据包。

2) 从服务器发送 UDP 数据包 -> 客户端可以正常工作,因为我可以看到客户端收到了数据包。

3) 当客户端尝试同时发送和读取时,它会向服务器发送数据,但不会读取响应。

任何帮助将不胜感激!

【问题讨论】:

  • 您是否取消了对Bind 的呼叫的注释?而且,Receive 不应该使用receiveEndPoint。该参数将由该函数填充远程端点。
  • @BiesiGrr 我尝试取消注释绑定,但它崩溃说:System.Net.Sockets.SocketException:'请求的地址在其上下文中无效'并且我更新了接收。
  • 您的receiveEndPoint 应该是new IPEndPoint(IPAddress.Any, port)。您传递给BindEndPoint 必须是本地的,而不是远程服务器上的。
  • @BiesiGrr 我在你发表评论之前更新了它:) 现在接收看起来不错吗?
  • 除了绑定部分,您还需要更新您的Console.WriteLine 以现在改为使用remoteEP

标签: c# sockets networking udp


【解决方案1】:

你的接收函数应该是这样工作的

void readerUdpClient()
{
    new Thread(() => {
        UdpClient readerClient = new UdpClient(receivePort);  
        Console.WriteLine("Awaiting data from server...");
        var remoteEP = new IPEndPoint(IPAddress.Any, 0);
        byte[] bytesReceived = readerClient.Receive(ref remoteEP);
        Console.WriteLine($"Received {bytesReceived.Length} bytes from {remoteEP}");
    }).Start();
}

采用端口的UdpClient constructor 会自动为您绑定本地端点。

【讨论】:

  • 非常感谢!我真的很感谢你的帮助,我们被困了很长时间,你救了我们:)
猜你喜欢
  • 2012-10-03
  • 2012-05-20
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2011-11-22
  • 2012-05-09
相关资源
最近更新 更多