我通过包装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交换)?
答案 0 :(得分:1)
我不想阻塞等待服务器确认我的上一条消息,因为这会给我的代码用户带来另一个延迟/失败点。它不是我的协议的重要信息,只是一个很好的。
我假设您正在谈论应用程序级别的ACK。如果您在发送者到达之前关闭,未读数据将激发RST给发件人。你必须决定这一点。要么它在协议中,要么它不是。