发送后没有阻塞的TCP套接字和刷新?

时间:2012-07-15 10:25:46

标签: c++ sockets tcp nonblocking flush

我正在为我的应用程序使用Windows套接字(winsock2.h)。由于阻塞套接字不允许我控制连接超时,我使用非阻塞套接字。发送命令后,我正在使用shutdown命令刷新(我必须)。我的超时是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);

2 个答案:

答案 0 :(得分:0)

  

非阻塞TCP套接字并在发送后立即刷新?

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

  

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

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

  

我使用的是非阻塞的。

Non sequitur。

  

发送命令后,我正在使用shutdown命令刷新(我必须)。

您不必,shutdown()不会刷新任何内容。

  

我的超时是50毫秒

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

  

我想知道的是,如果要发送的数据太大,是否存在仅发送一部分数据或根本不发送任何数据的风险?

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

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

  

我希望尽快发送数据。

你做不到。 TCP实现流量控制。你无能为力。你受到接收者的限制。

  

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

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

  

或接收。

你无能为力:见上文。

  

因此,连接和写入都应该在最长50ms内完成,因为在我的情况下,时间非常重要。

见上文。对于花费可变时间的操作实现固定超时没有意义。 50ms对于连接超时来说太短了。如果这是一个真正的问题,你应该保持连接打开,以便连接延迟只发生一次:实际上你应该尽可能长时间地保持TCP连接打开。

  

我必须刷新写入和读取流

你做不到。 TCP中没有可以刷新读取流或写入流的操作。

  

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

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

  

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

运气不好。你必须阅读它。 [如果您使用的是BSD Unix,则可能会关闭套接字以进行输入,这会导致服务器上的数据被丢弃,但这在Windows上无效:它会导致服务器重置连接。]

答案 1 :(得分:-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;

}