我们应该在接受连接后等待多长时间检查可用数据?

时间:2016-03-25 01:08:27

标签: c# .net sockets .net-micro-framework

情况

我们使用以下代码接受传入的HTTP请求。

var localEndPoint = new IPEndPoint(IPAddress.Any, Port);

var serverSocket = new Socket(
    AddressFamily.InterNetwork,
    SocketType.Stream,
    ProtocolType.Tcp);

serverSocket.Bind(localEndPoint);
serverSocket.Listen(backlog: 25);

while (true)
{
    using (var clientSocket = serverSocket.Accept())
    {
        if (clientSocket.Available > 0)
        {
            var builder = new StringBuilder();

            while (clientSocket.Available > 0)
            {
                var currentBytes = new byte[clientSocket.Available];
                var bytesReceived = clientSocket.Receive(currentBytes);

                var currentBytesString = 
                    new string(Encoding.UTF8.GetChars(currentBytes));

                builder.Append(currentBytesString);
            }
        }
    }
}

问题

即使连接有数据,有时clientSocket.Available也为零。我们实现的解决方案是在接受连接之后等待,然后再检查数据是否可用。我们这样做:

var start = DateTime.Now;
var duration = new TimeSpan(0);
while (clientSocket.Available <= 0 || duration.Milliseconds < 1000)
{
    duration = DateTime.Now - start;
    Thread.Sleep(100);
}

问题

接受连接后,我们需要等待多长时间才能在套接字中提供连接数据?

工作解决方案

感谢szym为这种方法提供灵感。它现在正在运作。

while (true)
{
    using (var clientSocket = serverSocket.Accept())
    {
        var builder = new StringBuilder();

        do
        {
            var currentBytes = new byte[50];
            var bytesReceived = clientSocket.Receive(currentBytes);

            var currentBytesString = 
                new string(Encoding.UTF8.GetChars(currentBytes));

            builder.Append(currentBytesString);
        }
        while (clientSocket.Available > 0);
    }
}

1 个答案:

答案 0 :(得分:1)

通常,您可能需要等待一段时间(想想具有巨大往返时间的糟糕网络),某些平台上的默认超时为20秒!

但是,在困循环中检查Available的方法是轮询,这是浪费CPU。您应该阻止等待数据到达的Receive(如果您需要处理多个连接,可能会生成一个线程),或者使用非阻塞方法。

引用documentation(强调我的):

  

如果您使用非阻止套接字,则可以使用“可用”   在调用Receive之前确定数据是否排队等待读取。   可用数据是网络中排队的数据总量   阅读缓冲区。如果网络缓冲区中没有数据排队,   可用返回0。