2

我正在为我的应用程序使用 Windows 套接字(winsock2.h)。由于阻塞套接字不允许我控制连接超时,因此我使用的是非阻塞套接字。在发送命令之后,我正在使用关闭命令进行刷新(我必须)。我的超时时间是 50 毫秒,我想知道的是,如果要发送的数据这么大,是否存在只发送一部分数据或什么都不发送的风险?提前致谢...

    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    u_long iMode=1;
    ioctlsocket(hSocket,FIONBIO,&iMode);
    connect(hSocket, (sockaddr*)(&sockAddr),sockAddrSize);
    send(hSocket, sendbuf, sendlen, 0);
    shutdown(hSocket, SD_BOTH);
    Sleep(50);
    closesocket(hSocket);
4

2 回答 2

1

发送后立即进行非阻塞 TCP 套接字和刷新?

没有刷新 TCP 套接字这样的事情。

由于阻塞套接字不允许我控制连接超时

错误的。您可以select()在阻塞套接字上使用。

我正在使用非阻塞的。

不合逻辑的推论。

在发送命令之后,我正在使用关闭命令进行刷新(我必须)。

你不必,shutdown()也不会冲洗任何东西。

我的超时时间是 50 毫秒

为什么?发送数据的时间取决于数据的大小。明显地。使用固定超时进行发送没有任何意义。

我想知道的是,如果要发送的数据如此之大,是否存在只发送一部分数据或什么都不发送的风险?

在阻塞模式下,send()如果可能,您提供给的所有数据都将被发送。在非阻塞模式下send(),如果可能,将发送由返回值表示的数据量。无论哪种情况,如果发送失败,连接将被重置。无论您叠加什么超时机制,都不可能改变其中的任何一个:具体来说,在超时后异步关闭套接字只会导致关闭附加到正在发送的数据中。它不会导致发送中止。

您的代码不会通过任何人类已知的代码审查。零错误检查;睡眠完全没有意义;关闭之前关闭是多余的。如果睡眠旨在实现超时,则不会。

我想尽可能快地发送数据。

你不能。TCP 实现流量控制。您对此无能为力。您受到接收器的速率限制。

另外两种可能的情况是:服务器等待太长时间以接受连接

没有这种情况。客户端可以在服务器调用之前完成连接accept().如果您尝试实现比默认值短一分钟的连接超时,请使用select().

或接收。

您对此无能为力:见上文。

所以连接和写入都应该在最多 50 毫秒内完成,因为在我的情况下时间非常重要。

往上看。为需要可变时间的操作实现固定超时是没有意义的。而且 50 毫秒对于连接超时来说太短了。如果这是一个真正的问题,您应该保持连接打开,以便连接延迟只发生一次:事实上,您应该尽可能长时间地保持 TCP 连接打开。

我必须刷新写入和读取流

你不能。TCP 中没有任何操作会刷新读取流或写入流。

因为服务器不断向我发送不必要的大数据,而且我的互联网连接有限。

另一个不合逻辑的。如果服务器向您发送数据,您必须读取它,否则您将停止服务器,这与刷新您自己的写入流没有任何关系。

实际上我什至不想要来自服务器的单个字节

厄运。你必须阅读它。[如果你在 BSD Unix 上,你可以关闭用于输入的套接字,这会导致来自服务器的数据被丢弃,但这在 Windows 上不起作用:它会导致服务器重置连接。]

于 2016-01-25T20:44:14.893 回答
-2

感谢 EJP 和 Martin,现在我创建了第二个线程来检查。同样在我在问题中发布的代码中,我添加了“counter=0;” “发送”行之后的行并删除了关机。它就像我现在想要的那样工作。它永远不会等待超过 50 毫秒 :) 非常感谢

unsigned __stdcall SecondThreadFunc( void* pArguments )

{

while(1)
{
    counter++;
    if (counter > 49)
    {
        closesocket(hSocket);
        counter = 0;
        printf("\rtimeout");
    }

    Sleep(1);
}
return 0;

}

于 2012-07-15T11:56:57.030 回答