首页 > 解决方案 > C# 异步 UDP 服务器 - 如何将套接字传递给回调

问题描述

我正在尝试编写一个异步 udp 服务器,但我很难理解其中一些东西是如何工作的。在这段代码中,程序在 ClientConnected() 方法上停止,说 asyncResult.asyncstate 作为套接字为空,那么我如何将发送方的套接字传递给回调?

class UDPServer
{
byte[] byteData;
int bufferSize;

public ManualResetEvent allDone = new ManualResetEvent(false);

Socket serverSocket;
IPEndPoint localIPEP;
EndPoint sender = new IPEndPoint(IPAddress.Any, 0);

IPEndPoint[,] playerList = new IPEndPoint[5000, 2]; // 5000 possible player lobbies, each with 2 player ip addresses and ports
int playerListIndex = 0; // we start filling up the lobbies from 0

bool waitingForSecondClient;

public UDPServer(IPEndPoint serverIpEndPoint)
{
    bufferSize = 1024;
    byteData = new byte[1024];


    localIPEP = serverIpEndPoint;
    serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

    serverSocket.Bind(localIPEP);

    Console.WriteLine("Server setup complete.");
}

public void GetConnection()
{
    while (true)
    {
        allDone.Reset();
        Console.WriteLine("Waiting for new client.");
        serverSocket.BeginReceiveFrom(byteData, 0, bufferSize, SocketFlags.None, ref sender, ClientConnected, sender);
        allDone.WaitOne();
    }
}

public void ClientConnected(IAsyncResult asyncResult)
{
    allDone.Set();

    byte[] data = new byte[1024];
    data = byteData;
    byteData = null;
    Socket clientSocket = asyncResult.AsyncState as Socket;
    EndPoint remote = clientSocket.LocalEndPoint;
    int bytesReceived = serverSocket.EndReceiveFrom(asyncResult, ref remote);
    string message = Encoding.ASCII.GetString(data, 0, bytesReceived);
    remote = new IPEndPoint(IPAddress.Any, 0);
    serverSocket.BeginReceiveFrom(byteData, 0, bufferSize, SocketFlags.None, ref remote, ClientConnected, remote);


    Console.WriteLine("-------------");
    Console.WriteLine("Received bytes of data: " + bytesReceived);
    Console.WriteLine("-------------");
    Console.WriteLine("Received string: " + message);
    Console.WriteLine("-------------");

    if (message.Equals("New client"))
    {
        Send(clientSocket, "Hello");
    }

标签: c#asynchronousserverudp

解决方案


我也有这个错误,我最终解决了它,就像这样

示例:github上的示例

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

public class UdpListenZ
{ 
    public List<Socket> connections { get; private set; } = new List<Socket>();
    public IPAddress address { get; private set; } = IPAddress.Any;
    public int port { get; private set; } = 0;
    public IPEndPoint localEndPoint { get; private set; } = new IPEndPoint(0, 0);
    public Socket listen { get; set; } = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    private byte[] received { get; set; } = new byte[1];
    private EndPoint point = new IPEndPoint(IPAddress.Any, 0);
    public event EventZ.Connect OnConnect;
    public event EventZ.Receive OnReceive;
    public event EventZ.Disconnect OnDisconnect;

    public void Init(IPAddress address, int port)
    {
        this.address = address;
        this.port = port;
        this.localEndPoint = new IPEndPoint(address, port);
    }

    public void Start()
    {
        listen.Bind(localEndPoint);
        ReceiveNow();
    }

    private void ReceiveNow()
    {
        received = new byte[1024 * 4];
        point = new IPEndPoint(IPAddress.Any, 0) as EndPoint;
        listen.BeginReceiveFrom(received, 0, received.Length, SocketFlags.None, ref point, Receive, point);
    }

    private void Receive(IAsyncResult result)
    {
        var point = result.AsyncState as EndPoint;
        var size = listen.EndReceiveFrom(result, ref point);
        var data = new byte[size];
        Array.Copy(received, data, data.Length);

        OnReceive?.Invoke(data, point);

        ReceiveNow();
    }

    public void Stop()
    {
        listen?.Close();
    
        connections.Clear();

        listen?.Dispose();
    }
}

推荐阅读