我正在为我的应用程序使用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);
答案 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;
}