【问题标题】:Close socket without waiting for send to succeeed - Winsock2 non-blocking TCP socket关闭套接字而不等待发送成功 - Winsock2 非阻塞 TCP 套接字
【发布时间】:2014-11-01 05:58:51
【问题描述】:

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

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

  • 向服务器发送最终消息
  • 关闭套接字并销毁窗口

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

目前,我的代码最终调用 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 交换)而不必阻塞?

【问题讨论】:

  • 我不确定我是否理解;既然这是一个非阻塞套接字,为什么最终读取需要是阻塞读取?
  • @HarryJohnston 我破坏了套接字通知将要进入的模式窗口,因此无法进行非阻塞读取
  • 啊。您能否改为隐藏窗口,并在完全关闭连接后将其销毁?
  • @HarryJohnston 也许,我会调查的。我的代码在一个 DLL 中,该 DLL 被加载到我无法控制的代码进程中,因此任何接受消息的非模态窗口都依赖于具有健全的消息循环的第三方......而且我对依赖它持谨慎态度一般 :) 但是感谢您的想法,它可能仍然可行。

标签: c++ windows tcp winsock2


【解决方案1】:

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

我假设您说的是应用程序级 ACK。如果您在未读数据到达之前关闭未读数据,则会向发件人发送 RST。您必须对此做出决定。要么在协议中,要么不在。

【讨论】:

  • 我说的是 TCP ACK。如果有网络拥塞,那么这可能会很慢到达,我不希望我的 UI 在网络很慢时不得不等待,或者在此操作期间出现故障。
  • 你是说唯一的选择是,(a)在关闭套接字之前等待响应数据包,或者(b)关闭套接字并进行 RST 吗?
  • 那我不知道你在说什么。您不能以任何方式“阻塞等待服务器到ACK我的最后一条消息”或“等待响应数据包”。您没有任何 API 可以这样做。 API 使您对ACKs. 的可见性为零,您只需发送和关闭即可。 RSTs 通常是由未读的 application 数据引起的。比如你好像忘记了Len=1380的那个。
  • 好的。然后假设我知道服务器会响应我的消息,但我不想等待。
  • 然后你会激起 RST。处理这种情况的最干净的方法实际上是关闭套接字以进行输出,读取所有输入直到流结束,然后关闭。在两端。然后你根本没有得到 RST,但你得到了读取延迟。或者只是忍受重置,以及它们在对等方造成的后果。
猜你喜欢
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 2011-05-31
  • 2010-10-31
  • 2013-10-15
  • 1970-01-01
相关资源
最近更新 更多