我需要做的只是从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毫秒(在这个具体情况下)在第一次迭代后等待,这绝对不是它应该做的方式。
有可能吗?我的意思是一些有效的方法。
答案 0 :(得分:2)
有一种从套接字异步读取n个字节的方法
不,没有。有一种方法使用非阻塞模式和select()
重新实现阻塞模式。什么都没有异步&#39;无论如何。从调用者的角度来看,它是阻塞模式。它构思得很糟糕,确实是错误的,应该被抛弃。您发布的代码完全没有意义。它只是实现阻塞读取循环的一种复杂方式。使用阻止模式。实际上,您已经是,但有更多的系统调用。并丢失了select()
电话和EAGAIN / EWOUDLBLOCK的内容。
我必须使用它来实现另一个读取所有可用字节的方法。 ... 正如你所看到的那样,read()使用select()来等待传入数据,因此使用固定大小的缓冲区(循环中)可能导致500 ms(在这个具体情况下)在第一次迭代后等待
不,不是。 select()
将立即返回套接字上的数据。没有500ms,除非没有数据。并且使用固定大小的缓冲区&#39;与它完全无关。
这绝对不是它应该做的方式。
这不是它的完成方式。
这里没有问题需要解决。