Java 在从套接字读取数据后,停止套接字并等待超时

Java 在从套接字读取数据后,停止套接字并等待超时,java,sockets,http,network-programming,socket-timeout-exception,Java,Sockets,Http,Network Programming,Socket Timeout Exception,我正在尝试使用tcp套接字创建JavaHTTP服务器。HTTP 1.1有一个超时值,该值将使连接保持不变,并等待一段时间,以获取来自客户端的可能数据。我试图通过使用:clientSocket.setSoTimeout()在程序中实现此计时器。尽管这将有助于让连接保持打开状态一段时间,但它将在允许读取下一个请求之前等待确切的时间 例如: 如果超时设置为5秒 请求1已读取。然后,套接字挂起并等待5秒结束。 请求2已读取。套接字将等待5秒,直到再次启动 如果我的超时设置为大值,则会出现问题。不应出现这

我正在尝试使用tcp套接字创建JavaHTTP服务器。HTTP 1.1有一个超时值,该值将使连接保持不变,并等待一段时间,以获取来自客户端的可能数据。我试图通过使用:
clientSocket.setSoTimeout()
在程序中实现此计时器。尽管这将有助于让连接保持打开状态一段时间,但它将在允许读取下一个请求之前等待确切的时间

例如:

如果超时设置为5秒

请求1已读取。然后,套接字挂起并等待5秒结束。
请求2已读取。套接字将等待5秒,直到再次启动

如果我的超时设置为大值,则会出现问题。不应出现这种情况,因为请求应在收到后立即处理,只有在指定的持续时间内未收到数据时,超时才会过期

有谁能告诉我如何解决这个问题吗

编辑:

对于面临类似问题的人,以下是我的解决方案:


由于客户机在接收所有数据之前等待超时,我猜客户机不知道来自服务器的所有数据都已接收。因此,我在HTTP响应包中添加了一个内容长度字段。现在,我的客户端在收到数据后不再挂起。setSoTimeout确实如所述工作

好的,当您收到连接时,请启动一个新线程,如下所示:

class ClientService extends Thread {

    private final Socket clientSocket;

    public ClientService(Socket clientSocket) {
      this.clientSocket=clientSocket;
    }

    public void run() {
      // do your work with the Socket clientSocket here
    }

}
这就是服务器代码的外观:

while (true) {
    Socket clientSocket = server.accept();
    new ClientService(clientSocket).start();
}
它将允许您处理响应,而无需等待对方直到超时

HTTP 1.1有一个超时值,该值将使连接保持不变,并等待一段时间,以获取来自客户端的可能数据

不是真的。它有一个connection:keep-alive设置,这是默认行为,它允许端点关闭闲置一段时间后未使用的连接,但它本身没有timeout属性

我正试图通过使用:clientSocket.setSoTimeout()在程序中实现此计时器

这与HTTP没有任何关系。这是套接字读取超时

尽管这将有助于让连接保持打开状态一段时间,但它将在允许读取下一个请求之前等待确切的时间

不会的。如果在超时时间内没有数据到达,它将导致读取方法抛出
SocketTimeoutException
。没有别的了

例如:

如果超时设置为5秒

请求1已读取。然后,套接字挂起并等待5秒结束

不,没有

请求2已读取。套接字将等待5秒,直到再次启动

不,没有。这些都是你编的。这是幻想

如果我的超时设置为大值,则会出现问题

无论超时值大小,这都不是问题,因为它根本不会发生

不应出现这种情况,因为请求应在收到后立即处理,只有在指定的持续时间内未收到数据时,超时才会过期

这正是Socket.setSoTimeout()所做的


你的问题是建立在一个谬误上的。

你能展示一下你的一些代码吗?可能是接受客户端的部分?我只使用了一行来接受客户端:
client=server.accept()它被放入
while(true)
循环中,以持续侦听连接。当然,但接下来会发生什么?我怀疑,您没有将处理客户机的任务传递给另一个线程,但是如果没有看到任何代码,就很难判断确切的问题所在。这就是为什么他们在帮助中心谈论“最小、完整和可验证的示例”。我的服务器没有使用任何多线程。是否可以在不使用多线程的情况下执行超时?“持久连接”并不意味着“服务器将通过同一连接发送响应”。HTTP中总是这样。这意味着客户端可以通过同一连接发送更多请求。HTTP什么都不做。实现可以做到这一点。你在实现它:你做到了。你需要对HTTP有更好的了解,这比你目前在这个项目中所需要的要好得多。我只处理一个具有单一持久连接的客户端。所以应该不需要多线程,对吗?简单的回答是:不需要。即使使用单客户端,您的连接也可以挂起直到超时,如果您希望客户端能够在不等待前一个连接完成的情况下创建另一个连接,那么您需要多线程。在很多情况下,客户端可以断开连接并尝试立即重新连接,而无需多线程处理,它需要等待上一个“死”连接超时,然后让另一个连接被处理。如果我使用setSoTimeout(),套接字会在收到数据后立即停止等待吗?@LanceHAOH当然会。暂停了。在超时内到达数据=>没有超时。如果我将超时设置为一个大值,我观察到在发送下一个请求之前有一个很长的延迟。每次读取请求后,套接字都会引发超时异常。然后客户端必须建立一个新连接才能下载下一个文件。这不足以证明我的观点吗?当您读取下一个请求时,套接字会抛出超时异常。不是“每次请求读取后”。插座并不是自动“挂起直到5秒结束”。下一个请求之前的延迟意味着客户端没有在超时时间内发送一个请求,因此您得到了一个读取超时,因此您得到了一个
SocketTimeoutException
,正如我上面所说的。因此,您刚才正确地实现了服务器端连接空闲超时。我不知道这能证明你的观点,但是