c# - 使用UDP接收和处理连续数据包

标签 c# .net sockets udp asynccallback

这是我当前的设置(使用 UDP):

void OnDataReceived(IAsyncResult result)
{

    IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

    byte[] buffer = socket.EndReceive(result, ref ep);

    Packet p = new Packet(Encoding.ASCII.GetString(buffer, 0, buffer.Length));

    //process packet

    socket.BeginReceive(new AsyncCallback(OnDataReceived), socket);

}

我想知道如果我在调用 EndReceive 之后立即调用 socket.BeginReceive 然后处理数据包以获得像这样的连续数据包流会发生什么:

void OnDataReceived(IAsyncResult result)
{

    IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

    byte[] buffer = socket.EndReceive(result, ref ep);
    socket.BeginReceive(new AsyncCallback(OnDataReceived), socket);

    Packet p = new Packet(Encoding.ASCII.GetString(buffer, 0, buffer.Length));

    //process packets

}

如果我一调用 BeginReceive 就收到一个数据包,这会不会与当前的数据包处理产生某种冲突?

此外,如果这不会发生冲突,那么更改为 TCP 是否会使它失效?

最佳答案

看起来您正在那里创建某种递归处理程序。我不确定这将如何工作,可能不是很好。我通常会选择一个单独的读取器线程来监听传入的数据并将其传递给事件。这在过去对我很有帮助。不过,我还没有考虑为此使用异步。

下面是一些示例代码,说明如何使用单独的线程来处理传入的 UDP 数据。它不完整,但应该让您了解如何设置它。

    private Thread _udpReadThread;
    private volatile bool _terminateThread;

    public event DataEventHandler OnDataReceived;
    public delegate void DataEventHandler(object sender, DataEventArgs e);

    private void CreateUdpReadThread()
    {
        _udpReadThread = new Thread(UdpReadThread) { Name = "UDP Read thread" };
        _udpReadThread.Start(new IPEndPoint(IPAddress.Any, 1234));
    }

    private void UdpReadThread(object endPoint)
    {
        var myEndPoint = (EndPoint)endPoint;
        var udpListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        // Important to specify a timeout value, otherwise the socket ReceiveFrom() 
        // will block indefinitely if no packets are received and the thread will never terminate
        udpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100);
        udpListener.Bind(myEndPoint);

        try
        {
            while (!_terminateThread)
            {
                try
                {
                    var buffer = new byte[1024];
                    var size = udpListener.ReceiveFrom(buffer, ref myEndPoint);
                    Array.Resize(ref buffer, size);

                    // Let any consumer(s) handle the data via an event
                    FireOnDataReceived(((IPEndPoint)(myEndPoint)).Address, buffer);
                }
                catch (SocketException socketException)
                {
                    // Handle socket errors
                }
            }
        }
        finally
        {
            // Close Socket
            udpListener.Shutdown(SocketShutdown.Both);
            udpListener.Close();
        }
    }

    public class DataEventArgs : EventArgs
    {
        public byte[] Data { get; private set; }
        public IPAddress IpAddress { get; private set; }

        public DataEventArgs(IPAddress ipaddress, byte[] data)
        {
            IpAddress = ipaddress;
            Data = data;
        }
    }

关于c# - 使用UDP接收和处理连续数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13659999/

相关文章:

python - 我可以将 Python 脚本作为服务运行吗?

string - 音频文件可以包含换行符吗?

c# - Windows 8 Metro 打开网站/mailto C#

c# - 显示框显示两次 C#

c# - 传入字典的模型项是 'MyType' 类型的,但是这个字典需要一个 'MyType' 类型的模型项

c# - 放大屏幕的特定区域

c# - 如何强制应用程序使用不同的配置文件?

sql - 使用scope_identity()执行嵌套批量插入的最快方法?

java - AsyncTask 更好的通信协议(protocol)

c# - Quartz.NET - 使用 IJobListener 获取作业异常