UDP 客户端收不到任何数据

UDP Client can't receive any data

我已经开始学习 System.Net,并编写了一个简单的 UDP 客户端-服务器聊天应用程序。

为了简单起见,客户端和服务器都位于我的机器上(通过本地)。

我可以从客户端向服务器发送一条消息并将其写在那里,但在那之后,客户端也应该收到一条硬编码消息(你好!),这是我的问题。

Screenshot of application (server and client)

客户代码:

public class UDPClient
        {
            private Socket clientSocket;
            private EndPoint epSend, epRecieve;

            private byte[] dataBuffer;
            private ArraySegment<byte> dataBufferSegments;

            /// <summary>
            /// initializing client with buffer, end points of server and client (for sending and listening)
            /// </summary>
            /// <param name="address"></param>
            /// <param name="port">for future port-forwarding</param>
            public void Initialize(IPAddress address, int port = 0)
            {
                dataBuffer = new byte[4096];
                dataBufferSegments = new ArraySegment<byte>(dataBuffer);

                epRecieve = new IPEndPoint(address, clientListenOn);
                epSend = new IPEndPoint(address, serverListenOn);

                Console.WriteLine(epRecieve.Serialize());
                Console.WriteLine(epSend.Serialize());

                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                clientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
            }

            /// <summary>
            /// async task for listening on packets
            /// </summary>
            public void Listen()
            {
                _ = Task.Run(async () =>
                {
                    SocketReceiveMessageFromResult res;
                    while (true)
                    {
                        res = await clientSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);

                        Console.WriteLine(Encoding.UTF8.GetString(dataBuffer, 0, bufferSize));
                    }
                });
            }
            /// <summary>
            /// async task for sending data back to server
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public async Task Send(byte[] data)
            {
                var s = new ArraySegment<byte>(data);
                await clientSocket.SendToAsync(s, SocketFlags.None, epSend);
            }
        }

服务器代码:

    /// <summary>
    /// UDP Server
    /// </summary>
    public class UDPServer
    {
        private Socket serverSocket;
        private EndPoint epRecieve, epSend;

        private byte[] dataBuffer;
        private ArraySegment<byte> dataBufferSegments;

        public void Initialize()
        {
            dataBuffer = new byte[4096];
            dataBufferSegments = new ArraySegment<byte>(dataBuffer);

            epRecieve = new IPEndPoint(IPAddress.Loopback, serverListenOn);

            Console.WriteLine(epRecieve.Serialize());

            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            serverSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
            serverSocket.Bind(epRecieve);
        }

        public void Listen()
        {
            _ = Task.Run(async () =>
            {
                SocketReceiveMessageFromResult res;
                while (true)
                {
                    res = await serverSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);
                    Console.WriteLine(Encoding.UTF8.GetString(dataBuffer, 0, bufferSize));

                    Console.WriteLine(res.RemoteEndPoint);
                    Console.WriteLine(res.ReceivedBytes.ConvertToString());
                    Console.WriteLine(res.PacketInformation.Address);

                    epSend = new IPEndPoint(res.PacketInformation.Address, clientListenOn);

                    Console.WriteLine(epSend.Serialize());

                    //this doesn't seem to work...
                    await SendTo(epSend, Encoding.UTF8.GetBytes("Hello back!"));
                }
            });
        }

        public async Task SendTo(EndPoint recipient, byte[] data)
        {
            var s = new ArraySegment<byte>(data);
            await serverSocket.SendToAsync(s, SocketFlags.None, recipient);
        }
    }

服务器主代码:

static void Main(string[] args)
        {
            Network.UDPServer server = new Network.UDPServer();
            server.Initialize();
            server.Listen();

            Console.ReadLine();
        }

客户端主要代码:

static async Task Main(string[] args)
        {
            Network.UDPClient client = new Network.UDPClient();

            IPAddress ip = IPAddress.Loopback;
            Console.WriteLine(ip.ToString());

            client.Initialize(ip);
            client.Listen();
            await client.Send(Encoding.UTF8.GetBytes(Console.ReadLine()));

            Console.ReadLine();
        }

因此我希望任何人都能指出我的系统出了什么问题。

非常感谢!

我将您的代码粘贴到 Visual Studio 上并进行了一些小修改(缺少一些字段等),我遇到的问题如下:

在您的 UDP 客户端上,此行抛出类型为 InvalidOperationException 的异常。

System.InvalidOperationException: 'You must call the Bind method before performing this operation.'
res = await clientSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);

您需要将套接字绑定到本地端点,特别是您的接收端点。这样做是为了将该套接字与该特定端点相关联并从中接收数据。

            public void Initialize(IPAddress address, int port = 0)
            {
                dataBuffer = new byte[4096];
                dataBufferSegments = new ArraySegment<byte>(dataBuffer);

                epRecieve = new IPEndPoint(address, clientListenOn);
                epSend = new IPEndPoint(address, serverListenOn);

                Console.WriteLine(epRecieve.Serialize());
                Console.WriteLine(epSend.Serialize());

                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                clientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
                _clientSocket.Bind(_epRecieve);
            }

您可以在这里阅读更多内容: MSDN - Socket.Bind(EndPoint) Method