gpt4 book ai didi

c++ - 非阻塞套接字在 Windows 上丢失数据

转载 作者:行者123 更新时间:2023-11-28 06:23:39 25 4
gpt4 key购买 nike

我有一个支持所有连接客户端的非阻塞套接字服务器。它使用多线程,并且可以使用 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;

关于c++ - 非阻塞套接字在 Windows 上丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28903538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com