c# - 好的UDP中继服务器设计

标签 c# sockets udp rtp

我正在创建一个 UDP 服务器,它需要从各种客户端接收 UDP 数据包,然后将它们转发给其他客户端。我正在使用 C#,所以每个 UDP 套接字对我来说都是一个 UdpClient。我想我想要 2 个 UdpClient 对象,一个用于接收,一个用于发送。接收套接字将绑定(bind)到一个已知端口,而发送方根本不会绑定(bind)。

服务器会获取每个数据包,在数据包数据中查找用户名,然后根据服务器维护的路由列表,将数据包转发给 1 个或多个其他客户端。

我开始监听 UdpClient:

   UdpClient udpListener = new UdpClient(new IPEndPoint(ListenerIP, UdpListenerPort));
   udpListener.BeginReceive(new AsyncCallback(OnUDPRead), udpListener);

我的回调看起来像:

    void OnUDPRead(IAsyncResult ar)
    {
        UdpClient udpListener = (UdpClient)ar.AsyncState;

        try
        {
            IPEndPoint remoteEndPoint = null;
            byte[] packet = udpListener.EndReceive(ar, ref remoteEndPoint);

            // Get connection based on data in packet

            // Get connections routing table (from memory)

            // ***Send to each client in routing table***
        }
        catch (Exception ex)
        {
        }

        udpListener.BeginReceive(new AsyncCallback(OnUDPRead), udpListener);
    }

服务器每秒需要处理 100 个数据包(这是用于 VOIP)。我不确定的主要部分是在上面的“发送给每个客户”部分要做什么。我应该使用 UdpClient.Send 还是 UdpClient.BeginSend?由于这是针对实时协议(protocol)的,因此为任何给定客户端设置多个发送待处理/缓冲是没有意义的。

因为我在任何给定时间只发布了一个 BeginReceive(),我假设我的 OnUDPRead 函数在已经执行时永远不会被调用。除非 UdpClient 在这方面的工作方式与 TcpClient 不同?因为我没有给它一个缓冲区(我没有给它任何缓冲区),我想它可能会在只发布一个 BeginReceive 的情况下触发 OnUDPRead 几次?

最佳答案

我看不出有什么理由不能直接使用 one 套接字。在我看来,异步 I/O 在这种情况下并没有提供任何惊人的好处。只需使用非阻塞模式。收到一个数据包,发送它。如果 send() 导致 EAGAIN 或 EWOULDBLOCK 或任何 C# 表现形式,则将其删除。

在您的计划中,发送套接字将在您第一次调用 send() 时自动绑定(bind)。客户端将回复该端口。所以它需要是你正在阅读的端口。而您已经拥有其中之一。

关于c# - 好的UDP中继服务器设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10807490/

相关文章:

c# - 如何将另一个进程正在使用的数据库发送到电子邮件 C#

sockets - 带有 Golang 的蓝牙 RFCOMM 套接字

c++ - 如何将十六进制存储在数组中? C++ 多线程

c# - 多客户端,C#中的异步套接字,最佳实践?

c# - 如何从任何ip和任何端口接收UDP数据包?

java - Java UDP Server 增加内存

c# - 如何强制派生类包含具有默认值的某些属性

c# - 项目引用和方法签名问题

c# - 在 C# 中运行 Windows 窗体时访问和更改 txt 文档

c++ - 使用 QUdpSocket 作为 QIODevice 的正确方法是什么?