C ++非阻塞读取

时间:2017-03-28 19:49:42

标签: c++ linux sockets nonblocking

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

对具有定义大小的某些数据进行非阻塞读取:

  Sub CCount()
    Dim Count, Count, Count1 As Long
    Dim Arr() As Variant
    Dim n As Integer
    n = WorksheetFunction.CountA("I9:I32")
    Cells(9, 9).Select
    Count = 0
    ReDim Arr(1 To n)
    For Each Arr(n) In Range("I9:I32")

    If Arr(n).Value = Arr(n) And Arr(n).Offset(0, -2).Value = "Check" Then
    Count = Arr(n).Count
    Count1 = Count + Count1
    End If
    Next Arr(n)

    End Sub

所以我必须使用这种方法来实现像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)使用read()来等待传入数据,因此使用固定大小的缓冲区(循环中)可能会导致500毫秒(在这个具体情况下)在第一次迭代后等待,这绝对不是它应该做的方式。

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

1 个答案:

答案 0 :(得分:2)

  

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

不,没有。有一种方法使用非阻塞模式和select()重新实现阻塞模式。什么都没有异步&#39;无论如何。从调用者的角度来看,它是阻塞模式。它构思得很糟糕,确实是错误的,应该被抛弃。您发布的代码完全没有意义。它只是实现阻塞读取循环的一种复杂方式。使用阻止模式。实际上,您已经是,但有更多的系统调用。并丢失了select()电话和EAGAIN / EWOUDLBLOCK的内容。

  

我必须使用它来实现另一个读取所有可用字节的方法。   ...   正如你所看到的那样,read()使用select()来等待传入数据,因此使用固定大小的缓冲区(循环中)可能导致500 ms(在这个具体情况下)在第一次迭代后等待

不,不是。 select()将立即返回套接字上的数据。没有500ms,除非没有数据。并且使用固定大小的缓冲区&#39;与它完全无关。

  

这绝对不是它应该做的方式。

这不是它的完成方式。

这里没有问题需要解决。