与UDP中的不同端口通信



我刚开始用C#用.net进行套接字编程,我有一个关于我在机器上构建的实验服务器和客户端的问题。

我的任务是让客户端通过端口2004与服务器通信,让服务器通过端口2010与客户端通信。这意味着服务器在端口2004接收消息,并在端口2010发送消息。然而,我正在努力实现这一点。例如,这是否意味着服务器的本地端点为2004,远程端点为2010?或者我应该为此制作两个不同的插座吗?现在我的代码是这样的:

客户端

Socket sock;
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint clientEndpoint = new IPEndPoint(ipAddress, 2010);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 2004);
EndPoint remoteEP = (EndPoint)sender;
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.Bind(clientEndpoint);

服务器

IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Any, 2010);
remoteEP = (EndPoint)remoteEndpoint;
IPEndPoint localEndpoint = new IPEndPoint(ipAddress, 2004);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(localEndpoint);

我试着在Stackoverflow上查找其他问题,也阅读了learn.microsoft.com上的Socket文档,但我真的不知道如何做到这一点。我还想知道在这种情况下如何使用ReceiveFrom和SendTo,但我假设我只是接收并发送到远程端点?

我在现实生活中从未需要使用套接字,所以这主要是基于协议和文档的基本知识。

UDP是一种单向协议,所以如果你想要双向通信,你应该在每台计算机(或同一台计算机上的程序(上设置一个服务器和一个客户端,所以是的,你需要两个不同的套接字。以套接字为例,服务器应该看起来像:

using Socket listener = new(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
listener.Bind(localEndpoint);
listener.Listen(100);
var handler = await listener.AcceptAsync();
while (true)
{
// Receive message.
var buffer = new byte[1_024];
var receivedNoBytes = await handler.ReceiveAsync(buffer, SocketFlags.None);
var receivedString = Encoding.UTF8.GetString(buffer, 0, receivedNoBytes );
Console.WriteLine(receivedString);
}

客户:

using Socket client = new(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
await client.ConnectAsync(remoteEndpoint);
while (true)
{
// Send message.
var message = Console.ReadLine();;
var messageBytes = Encoding.UTF8.GetBytes(message);
_ = await client.SendAsync(messageBytes, SocketFlags.None);
}

在一台"计算机"上,您将使用2004作为localEndpoint端口,在另一台"电脑"上使用remoteEndpoint。因此,您可能希望将侦听端口和远程端口作为命令行参数,这样您就可以为这两个端口运行相同的程序实例。

请注意,listenerclient都在独立的无限循环中运行。因此,单个线程可以接收发送数据,而不能同时接收和发送数据。如果你想同时发送和接收,你可以在一个单独的线程上运行每个线程。另一种选择是在单个线程上交错发送接收消息,但这样一来,您需要等待响应才能发送下一条消息。所以我会使用两个线程的解决方案,但无论何时使用多个线程,您都应该对线程安全性感到满意。

还要注意的是,原始UDP没有真正的"UDP"概念;消息";。如果你想要更多的数据,你需要创建自己的协议来定义消息的开始和结束,以及错误处理等。更高级别的协议会为你处理这些问题,通常更容易使用。

最新更新