非阻塞套接字会丢失 Windows 上的数据
Non-blocking socket loses data on Windows
我有一个支持所有连接客户端的非阻塞套接字服务器。它使用多线程,并且可以使用GCC进行交叉编译。
它在 Linux 中完美运行(如我所愿),但是当我尝试在 Windows 中使用它时,当我通过它发送 70MB 的文件时,它会从文件中丢失大约 20MB。
所有套接字都是非阻塞的,因此对于接收/发送套接字调用,我没有检查/停止。它处于循环中,它发送它收到的内容,它有点充当 Echo 服务器,但它在 Windows 中丢失了数据。我在WSAStartup中使用Winsock 2.2。
怎么了?如何让等待/刷新发送呼叫,但从不阻止 recv 呼叫?(如果这是问题所在)
代码片段:我如何使其不阻塞:
iMode = 1;
ioctlsocket(sock1,FIONBIO, &iMode);
ioctlsocket(sock2,FIONBIO, &iMode);
如何在两个套接字之间发送/接收:
for (;;)
{
memset(buffer, 0, 8192);
int count = recv(sock1, buffer, sizeof(buffer), 0);
receiveResult = WSAGetLastError();
if (receiveResult == WSAEWOULDBLOCK && count <= 0)
continue;
if (count <= 0)
{
closesocket(sock1);
closesocket(sock2);
return;
}
if (count > 0)
{
int retval = send(sock2, buffer, count, 0);
}
}
int count = recv(sock1, buffer, sizeof(buffer), 0); receiveResult = WSAGetLastError(); if (receiveResult == WSAEWOULDBLOCK && count <= 0)
当调用 recv()
或 send()
时,WSAGetLastError()
只有在返回 -1 (SOCKET_ERROR
) 时才返回一个有意义的值,但你也会在返回 0 时检查它。 它们在返回>= 0 时不会为 WSAGetLastError()
设置错误代码。 您需要将这些条件分开。
此外,仅仅因为您已经读取了 X 个字节并不能保证您一次能够发送 X 个字节,因此您需要检查send()
是否有WSAEWOULDBLOCK
,直到您没有更多数据要发送。
尝试更多类似的东西:
bool keepLooping = true;
do
{
int count = recv(sock1, buffer, sizeof(buffer), 0);
if (count > 0)
{
// data received...
char *p = buffer;
do
{
int retval = send(sock2, p, count, 0);
if (retval > 0)
{
p += retval;
count -= retval;
}
else if (retval == 0)
{
// peer disconnected...
keepLooping = false;
}
else if (WSAGetLastError() != WSAEWOULDBLOCK)
{
// a real error occurred...
keepLooping = false;
}
else
{
// peer is not ready to receive...
// optionally use select() to wait here until it is...
}
}
while ((count > 0) && (keepLooping));
}
else if (count == 0)
{
// peer disconnected...
keepLooping = false;
}
else if (WSAGetLastError() != WSAEWOULDBLOCK)
{
// a real error occurred...
keepLooping = false;
}
else
{
// no data is available for reading...
// optionally use select() to wait here until it is...
}
}
while (keepLooping);
closesocket(sock1);
closesocket(sock2);
return;
相关文章:
- 从存储为 Windows 资源 (c++) 的 png 中获取 png 文件数据
- 加密在 Windows、C++ 和 Java 中传输中的数据
- readsome() 适合在 Windows 上读取二进制数据吗?
- 使用 pipe() 和 fdopen() 将数据从 Python 脚本传递到 Windows 中的C++应用程序
- 从 Windows 中的其他应用程序 GUI 中提取数据
- Windows 上的 Clang/LLVM 7 和 8 多次初始化内联静态数据成员(使用 link.exe 和 lld-
- C++ 即使数据可用,Windows recv() 也不会返回
- 在高数据包速率下最大限度地减少丢弃的 UDP 数据包 (Windows 10)
- 在 Ubuntu 中解析数据的速度比 Windows 10 快
- 使用Windows AES加密提供商在C 中解密C#加密数据
- 操纵Windows Explorer窗口时,UDP数据包会掉落
- Linux 在从文件中读取数据并放入矢量时比 Windows 快得多.txt.我将如何加速Windows以做同样的事情
- 使用 UDP 协议从 Windows 套接字发送到 Qt 套接字的网络数据包上的结构编码和解码
- 如何在 Windows 中保存特定于应用程序的数据
- 如何在Windows的Bash中流式传输大量数据
- 使用 Qt c++ 在 Windows Surface Pro 上获取加速度计数据
- 如何将序列化方法添加到作为Windows数据结构的类成员中,以便在C++中与boost序列化一起使用
- 如何获取 Windows 数据,如 CPU 使用率等
- 是否有跨平台(x86和x64)PInvoke和windows数据类型的明确指南
- 将Windows数据类型映射到.net