在C/C++中,如果客户端和服务器完成了3次握手,并且这个连接位于服务器的backlog(侦听队列)中。在服务器调用accept()
之前,如果客户端调用close()
会发生什么。是否将此连接从积压中删除?
一般来说,如果客户机调用close()
,客户机协议栈将发送一个FIN以指示客户机发送完毕,并等待服务器向客户机发送一个FIN,ACK(如我们将看到的那样,在html" target="_blank">服务器接受连接之前不会发生这种情况),然后客户机将对其进行ACK。这将是TCP连接的正常终止。
然而,由于TCP连接由两个或多或少的独立流组成,所以从客户端发送FIN实际上只是一个声明,表明客户端已经发送完数据(这通常被称为“半关闭”),而实际上并不是TCP协议级别上关闭连接的请求(尽管更高级别的协议通常会这样解释,但它们只能在连接被接受并且它们已经读取返回0字节以获知客户端已经完成写入)之后这样做。服务器仍然可以继续发送数据,但由于客户端已经调用了close()
,因此不再可能将此数据交付给客户端应用程序。如果服务器发送进一步的数据,客户端上的协议栈将以重置响应,导致TCP连接的异常终止。如果客户端实际上希望在声明发送数据完成后继续从服务器接收数据,那么它应该通过调用shutdown(sock,SHUT_WR)
而不是调用close()
来实现。
因此,这意味着超时和通常由客户端关闭的连接通常在服务器上保持活动状态,服务器将能够接受它们、读取请求、处理请求并发送回复,并且只有在客户端返回reset时才发现应用程序无法再读取回复。我之所以说“一般”是因为防火墙、代理和OS协议栈都对TCP连接可以保持半关闭状态的时间进行了限制,这通常违反了相关的TCP RFC,但出于“有效”的原因,例如处理DDoS。
我认为您所关心的是一个过载的服务器会因为客户端超时和重试而进一步过载,根据我前面的解释,我认为这是正确的。为了避免这种情况,客户端超时可以在调用close()
之前将SO_LINGER设置为0,这将导致发送重置,从而导致立即异常终止。我还建议对超时使用指数回退,以进一步减轻对过载服务器的影响。
[服务器]:
创建 TCP 客户端 最简单的方法来创建一个 TCP 客户端,使用默认选项如下所示: NetClient client = vertx.createNetClient(); 配置 TCP 客户端 如果你不想使用默认值,则创建TCP 客户端时,通过传入NetClientOptions实例可以配置: NetClientOptions options = new NetClientOptions().s
创建 TCP 服务器 使用最简单的方法来创建一个 TCP 服务器,使用所有默认选项如下所示: NetServer server = vertx.createNetServer(); 配置 TCP 服务器 如果你不想默认值,可以将服务器配置通过传入一个NetServerOptions实例来创建它: NetServerOptions options = new NetServerOptions().s
在探索和实现Proact设计模式后,遇到了一个问题,即客户端(“C”客户端)连接在限制后不再接受。开始探索netty。这是我试图做的1。C客户端建立连接2。Java服务器接受连接并开始使用TCP向客户端发送8 Mb大小的字节缓冲区。有什么想法吗?netty是一个好的选择吗?我浏览了netty的一个很好的例子,不幸的是不走运。 先谢谢你。 尊敬的Ravi
Vert.x 可以轻松地编写非阻塞的 TCP 客户端和服务器。
我不熟悉JAVA/Android TCP连接。我尝试实现一个TCP服务器,如下代码所示。 当我通过socket=serverSocket获取套接字时,我可以向客户端发送消息。accept() -----------------------------问题----------------------------- 我需要为客户端设置不同的端口吗?但是如何从多客户端获取多个套接字呢?