C++非阻塞读取

C++非阻塞读取

问题描述:

我需要做的就是从套接字读取所有可用字节.但有一个条件:有一种方法可以从非阻塞套接字读取 n 个字节,我必须使用它来实现另一种方法,该方法将读取所有可用字节.

All I need to do is just to read all available bytes from socket. But there is one condition: there is a method which reads n bytes from non-blocking socket which I have to use for implementation of another method which is going to read all available bytes.

非阻塞读取一些具有定义大小的数据:

Non-blocking reading of some data with defined size:

ssize_t read(void* buf, size_t len)
{
    ssize_t bytesRead = 0;
    ssize_t bytesTotallyRead = 0;
    size_t bytesLeftToRead = len;
    while (bytesTotallyRead < len)
    {
        bytesRead = ::recv(handle, (char*)buf+bytesTotallyRead, bytesLeftToRead, 0);
        if (bytesRead > 0)
        {
            bytesTotallyRead += bytesRead;
            bytesLeftToRead -= bytesRead;
        }
        else if (bytesRead == 0)
        {
            break;
        }
        else if (bytesRead < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else if (errno == EWOULDBLOCK)
            {
                int selectStatus(waitForIncomingData(500));
                if (selectStatus > 0)
                {
                    continue;
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
    }
    return (bytesRead==-1)?-1:bytesTotallyRead;
}

所以我必须使用这个方法来实现类似 ssize_t readAllAvailable(std::vector<uint8_t> &data) 的东西,它使用上面的方法来实现.

So I have to use this method to implement something like ssize_t readAllAvailable(std::vector<uint8_t> &data) which uses method above for it's implementation.

这里的问题,如您所见,read() 使用 select() 来等待传入数据,因此使用固定大小的缓冲区(循环中)可能导致在第一次迭代后等待 500 毫秒(在这种具体情况下),这绝对不是应该完成的方式.

The problem here, as you see, that read() uses select() for waiting for incoming data so using of buffer of fixed size (in loop) might lead to 500 ms (in this concrete case) waiting after 1st iteration and this is definitely not the way it should be done.

有可能吗?我的意思是一些有效的方法.

Is it possible at all? I mean some efficient ways.

有一种方法可以异步地从套接字读取 n 个字节

there is a method which reads n bytes from socket asynchronously

不,没有.有一种方法使用非阻塞模式和 select() 重新实现阻塞模式.没有任何关于它的异步".从调用者的角度来看,它是阻塞模式.它的构思很差,实际上是错误的,应该扔掉.您发布的代码完全毫无意义.这只是一种实现阻塞读取循环的复杂方法.使用阻塞模式.实际上,您已经是,但有更多的系统调用.并丢失 select() 调用和 EAGAIN/EWOUDLBLOCK 的东西.

No there isn't. There is a method which uses non-blocking mode and select() to reimplement blocking mode. There is nothing 'asynchronous' about it whatsoever. From the point of view of the caller it is blocking-mode. It is poorly, indeed incorrectly, conceived, and should be thrown away. The code you have posted is completely and utterly pointless. It's just a complicated way of implementing a blocking read loop. Use blocking mode. In effect, you already are, but with more system calls. And lose the select() call and EAGAIN/EWOUDLBLOCK stuff.

我必须使用它来实现另一种方法,该方法将读取所有可用字节....如您所见,这里的问题是 read() 使用 select() 来等待传入数据,因此使用固定大小的缓冲区(在循环中)可能会导致在第一次迭代后等待 500 毫秒(在这种具体情况下)

which I have to use for implementation of another method which is going to read all available bytes. ... The problem here, as you see, that read() uses select() for waiting for incoming data so using of buffer of fixed size (in loop) might lead to 500 ms (in this concrete case) waiting after 1st iteration

不,不是.select() 将立即返回套接字上可用的数据.除非没有数据,否则没有 500ms.而使用固定大小的缓冲区"与此完全无关.

No it isn't. select() will return immediately data becomes available on the socket. No 500ms unless there is no data. And 'using a buffer of fixed size' has exactly nothing to do with it.

这绝对不是应该做的.

事情不是这样的.

这里没有问题需要解决.

There is no problem here to solve.