c# - 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");
}
解决方案
我也有这个错误,我最终解决了它,就像这样
示例: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();
}
}
推荐阅读
- java - 如何根据 Firebase 信息重定向到不同的页面
- android - 从谷歌商店删除的应用程序和更新总是被旧的 apk 版本拒绝
- python - 左移熊猫数据框中的所有列
- forms - Yii 验证规则忽略 'on' 或 'except'
- javascript - 获取对 Potter api 的请求-返回字符列表-React
- docker - 詹金斯码头工人错误:java.io.FileNotFoundException
- php - Laravel 加载资源失败:net::ERR_CONNECTION_CLOSED
- java - Spring Kafka 消费者 - IllegalStateException:响应的相关 ID 与请求不匹配
- javascript - 根据对象中的属性计算可用时间
- docker - 如何缓存结果/层但在 Dockerfile 中仍然运行命令?