【发布时间】:2015-05-08 08:07:32
【问题描述】:
我有一个支持所有连接客户端的非阻塞套接字服务器。它使用多线程并且可以使用 GCC 进行交叉编译。
它在 Linux 中完美运行(如我所愿),但是当我尝试在 Windows 中使用它时,当我通过它发送 70MB 的文件时,它会从文件中丢失大约 20MB。
所有套接字都是非阻塞的,所以对于接收/发送套接字调用,我没有检查/停止。它在一个循环中,它发送它接收到的东西,它有点像一个 Echo 服务器,但它在 Windows 中丢失了数据。我在 WSAStartup 中使用 Winsock 2.2。
怎么了?我怎样才能等待/刷新发送呼叫,但从不阻止接收呼叫? (如果这是问题)
代码片段: 我如何使它成为非阻塞的:
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);
}
}
【问题讨论】:
-
如果
send和recv是非阻塞的,并且你正在接收到你正在发送的同一个缓冲区,会发生什么?那么同步呢? -
所以你认为问题是当我用缓冲区调用 send 时,它不会复制缓冲区并且在发送之前,数据被另一个 recv 调用覆盖?
-
这可能不是问题所在。否则你会从 memset 得到很多 0。 send 应该足够聪明,可以有一个内部缓冲区。
-
而且你没有检查之前的数据是否已经发送完毕。
-
@ehang,没错!我从来没有得到零。我只是在 75-80 MB 的文件中丢失了 20MB