【发布时间】:2018-06-22 16:31:12
【问题描述】:
我正在借助 JDK 提供的 ServerSocket 和 Socket API 用 Java 编写一个简单的 Web 服务器。我有一个 WebServer 类(一个“线程”),它有一个
ServerSocket serverSocket = new ServerSocket(8086);
并阻止
Socket clientSocket = serverSocket.accept();
我有一个带有 WebServer 类的固定线程池执行器。当客户端连接并取消阻止 .accept() 调用时,我创建一个 Connection 类的实例(一个“Runnable”并由我实现以处理请求并响应客户端)。将此实例传递给固定线程池执行器执行。 WebServer类中的循环如下图:
while(!Thread.interruped()) {
try {
final Socket client = this.serverSocket.accept();
logger.debug("WebServer: Incoming request!!");
final Connection connection = new Connection(client, this.rootPath);
this.threadPool.execute(connection);
} catch (IOException e) {
logger.error("Error listening on " + this.port + " because " + e.getMessage());
}
}
我还有一个简单的 html 表单,用于将数据“发布”到服务器。 html表单如下:
<html>
<body>
<h1>Blog post</h1>
<form id="blogPost" method="post" action="/POSTrequest">
Title: <input type="text" name="title"></input><br />
Text: <input type="text" name="text"></input><br />
<input type="submit" value="Submit" name="Submit">
</form>
</body>
</html>
考虑到它是 HTTP/1.1(keep-alive 行为),我已经保证,并且我必须在这个应用程序中实现,现在有 2 个问题:
1.) 每次我从网络浏览器发送 GET 请求以获取上述 html、提交表单(并实际发布数据)时,我都需要单击它两次(此不是双击)。在第一次单击时,请求标头为空(当我逐行解析请求时)。 就是在第二次点击按钮的时候,数据就发布好了,可以在服务器端得到很好的处理。 所有后续点击(直到我刷新页面)都一键提供。
2.)在我在第 1 点中提到的所有点击中。网页无限期地在服务器(在我的情况下为 localhost)等待响应,而据我说,我已经编写并刷新了适当的响应(200 OK 与其他标头,包括 Connection:keep-alive 和 Content-Length 中的正确长度)。
3.) 我还观察到,在响应 POST 请求时,即使在具有标头 Connection:keep-alive 并且不必关闭套接字或套接字的输入/输出流之后,还有另一个请求来自客户端(网页)进行连接(可能是 HTTP/1.1 的一个特征,即具有持久连接)。为什么会发生这种情况,既没有关闭套接字,也没有关闭流,也没有丢失 keep-alive 标头。
很抱歉在这篇文章中提出了多个问题。请提出您的问题,因为可能需要更多详细信息。感谢您的帮助!
还有关于使用 HTTP/1.1 在 Java 中进行套接字编程的有用链接吗?
【问题讨论】:
标签: java sockets post http-1.1 persistent-connection