c# - 套接字 OnData 事件

标签 c# sockets events

我现在有点不知所措。我有一些代码可以在数据可用时从套接字读取数据,但目前它在一个单独的线程上的 while 循环中,并且由于没有可用数据而在函数返回时消耗 50% 的 CPU。我真正想要的是 Sockets 的阻塞函数,它阻塞直到数据可用,或者至少是一个可以监听的 OnData 事件。我最初是从 AS3 (Flash) 转换这段代码的,但是他们的套接字类有我需要的 OnData 事件……只是用错了语言。

我目前在处理客户端连接的代码中有这段代码:

ServerThread = new Thread(() =>
{
    while (server.Connected && ServerContinue)
    {
        ReceiveFromServer(server, client);
    }

    Disconnect(server, client, false);
});

ServerThread.Start();

这是 ReceiveFromServer 中的代码:

bool isReady = false;
int messageLength = 0;
int dataAvailable = 0;
UInt16 packetSize = 0;
byte[] temp = new byte[2];
do
{
    dataAvailable = server.Available;
    if (isReady)
    {
        if (dataAvailable >= messageLength)
        {
            byte[] temp1 = new byte[2000];
            int bytesRead = server.Receive(temp1, 0, messageLength, SocketFlags.None);

            byte[] data = new byte[bytesRead + 2];
            Buffer.BlockCopy(temp1, 0, data, 2, messageLength);

            Helpers.ByteArray tempo = data;
            tempo.writeByte(temp[1]);
            tempo.writeByte(temp[0]);
            if (!VersionCheckPass)
            {
                Send(tempo, client);
                return;
            }

            ServerPacketHandler(tempo, client);
            messageLength = 0;
            isReady = false;
            temp = new byte[2];
        }
    }
    else if(dataAvailable > 2)
    {
        server.Receive(temp, 0, 2, SocketFlags.None);
        temp = temp.Reverse().ToArray();
        packetSize = BitConverter.ToUInt16(temp, 0);
        if (packetSize > 0)
        {
            messageLength = packetSize;
            isReady = true;
        }
    }
}
while (dataAvailable > 2 && dataAvailable >= messageLength && ServerContinue);

但这里的问题是,当 dataAvailable 为 0 时,函数简单地返回,然后在线程中再次调用 RecevieFromServer。这意味着通过简单地调用 ReceiveFromServer 然后再次返回会占用大量 CPU。

我目前在 ServerThread 中的 ReceiveFromServer 之后有 Thread.Sleep(10) 但这效率很低。所以我的问题是,有没有办法阻止直到数据可用或者是否有我可以处理的事件?或者其他人是否对如何做我目前正在做的同样的事情有任何建议,但它不会在没有可用数据的情况下无休止地循环。

最佳答案

找到了一个非常简单(且明显)的解决方案来阻塞直到数据可用。调用 Socket.Receive,接收大小为 0。套接字阻塞,直到有数据要接收,然后从套接字读取 0 字节,然后解除阻塞。它真的非常了不起 :) 下面是我如何实现它的:

ServerThread = new Thread(() =>
{
    byte[] zero = new byte[0];
    while (Server.Connected && ServerContinue)
    {
        server.Receive(zero, 0, SocketFlags.None);
        ReceiveFromServer(server, client);
    }

    Disconnect(server, client, false);
});

感谢所有的帮助。

乔希

关于c# - 套接字 OnData 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12870057/

相关文章:

c# - 有没有一种方法可以访问 .net 实体属性,而无需使用数组循环直接调用它?

java - 使用套接字在客户端-服务器应用程序中发送数据的最佳方式

sockets - 使用 ZeroMQ 实现消息总线

wpf - wpf mvvm datagrid选定的行

Javascript:如何检测单词是否突出显示

qt - QMetaCallEvent 的用途是什么以及如何访问其详细信息?

c# - Telnet 阻塞 C# TCP 服务器

c# - WPF和MVVM Light-通过Messenger关闭带有按钮的子窗口

c# - C# 中的 NeuralNet 单输出转换为多输出 c# dummy

c套接字发送的文件包含其他消息