Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关闭套接字而不等待发送成功-Winsock2非阻塞TCP套接字_C++_Windows_Tcp_Winsock2 - Fatal编程技术网

C++ 关闭套接字而不等待发送成功-Winsock2非阻塞TCP套接字

C++ 关闭套接字而不等待发送成功-Winsock2非阻塞TCP套接字,c++,windows,tcp,winsock2,C++,Windows,Tcp,Winsock2,我通过封装Winsock2API的套接字库使用非阻塞套接字。WSAAsyncSelect()函数用于将套接字通知发送到窗口。(应用程序是单线程的) 我正在尝试为开放式客户端套接字实现以下目标: 向服务器发送最后一条消息 关上插座,并摧毁窗户 我不想阻塞等待服务器确认我的最后一条消息,因为这会给我的代码用户带来另一个延迟点/故障。这对我的协议来说不是一个重要的信息,只是一个很好的信息 目前,我的代码最终调用Winsock2send()发送最后一条消息,然后调用closesocket()。但是,

我通过封装Winsock2API的套接字库使用非阻塞套接字。
WSAAsyncSelect()
函数用于将套接字通知发送到窗口。(应用程序是单线程的)

我正在尝试为开放式客户端套接字实现以下目标:

  • 向服务器发送最后一条消息
  • 关上插座,并摧毁窗户
我不想阻塞等待服务器确认我的最后一条消息,因为这会给我的代码用户带来另一个延迟点/故障。这对我的协议来说不是一个重要的信息,只是一个很好的信息

目前,我的代码最终调用Winsock2
send()
发送最后一条消息,然后调用
closesocket()
。但是,我的TCP流(由Wireshark查看)如下所示:

// Calling send():
Me -> Host:  [PSH, ACK] 

// Calling closesocket():
Me -> Host:  [FIN, ACK] 

// Just after that:
Host -> Me:  [ACK]    
Host -> Me:  [ACK]
Host -> Me:  [ACK] Len=1380   // A response to my sent packet, that I don't care about
Me -> Host:  [RST, ACK]
Host -> Me:  [RST]
Host -> Me:  [PSH, ACK]  // Retransmission of that response
Me -> Host:  [RST]
因此,Windows发送了两个RST请求。我认为这是因为套接字在发送
FIN
后接收到一条消息,因此它决定
RST
是必需的,但主机将其解释为重传请求

如果我在调用
closesocket
之前将代码更改为稍等,则跟踪看起来非常不同:我的一端只发送
[FIN,ACK]
,另一端发送
[FIN,ACK]
,并且没有RST

我的问题是:如何在不阻塞的情况下整齐地关闭套接字(即避免RST交换)

我不想阻塞等待服务器确认我的最后一条消息,因为这会给代码用户带来另一个延迟/失败点。这对我的协议来说不是一个重要的信息,只是一个很好的信息


我想您所说的是应用程序级ACK。如果在未读数据到达之前关闭,则未读数据将向发送方引发RST。你必须决定这件事。要么在协议中,要么不在协议中。

我说的是TCP确认。如果出现网络拥塞,那么到达的速度可能会很慢,我不希望我的UI在网络速度慢时不得不等待,或者在操作过程中出现故障。你是说唯一的选择是,(a)在关闭套接字之前等待响应包,或者(b)关闭套接字并进行RST?那么我不知道你在说什么。您不能以任何方式“阻塞等待服务器确认我的最后一条消息”或“等待响应数据包”。您没有这样做的API。API为您提供了
确认的零可见性。
您只需发送并关闭即可。RST通常由未读的应用程序数据引起。例如,您似乎忘记了带有
Len=1380
的一个。假设我知道服务器会响应我的消息,但我不想等待。然后你会挑起RST。处理这种情况最干净的方法实际上是关闭输出套接字,读取所有输入直到流结束,然后关闭。在两端。然后你根本没有RST,但是你得到了读取延迟。或者只是忍受重置,以及它们在同行中造成的后果。我不确定我是否理解;既然这是一个非阻塞套接字,为什么最终读取需要是一个阻塞读取?@HarryJohnston我破坏了套接字通知将要使用的模式窗口,因此不可能执行非阻塞读取。你能把窗户藏起来,在连接完全关闭后把它摧毁吗?@HarryJohnston也许,我会调查的。我的代码位于DLL中,DLL加载到我无法控制的代码进程中,因此任何非模式窗口接受消息都依赖于第三方拥有一个健全的消息循环。。。一般来说,我不太相信这一点:)但感谢你的想法,尽管如此,它还是可行的。