带 PrintWriter 的简单 Java 服务器 - 向浏览器发送响应时出现问题
我刚刚开始研究 HTTP 等,并编写了一个简单的 Java 客户端,它使用 URLConnection 将 URL 发送到服务器并下拉 index.html 页面(作为纯文本)。
现在我正在一个简单的服务器上工作,但我陷入了第一个障碍(也许是第二个或第三个),我无法让它正确响应客户端。
这是循环中的读取,它可以很好地读取 HTTP 请求,即使是来自 FF 和 IE 等:
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
问题是我不知道如何让它响应任何有用的内容。如果我让它做上面代码中正在做的事情,它会向我的客户端发送“某事”6次(因为HTTP请求有6行),但没有向FF/IE等发送任何内容。
而且,它似乎也没有当我在循环后添加一个 System.out.println("test");
行来打印时,就打破了循环,但服务器似乎从未达到这一点,不是吗? readLine() 应该在第一个 HTTP 请求结束时返回 null 吗?
我一直在阅读 sun 和 oracle 网站上的内容,但对于它应该如何工作仍然很困惑。
感谢您的宝贵时间,
Infinitifizz
编辑:哎呀,忘记复制代码了。
Server.java:
package exercise2;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
boolean listening = true;
ServerSocket server = new ServerSocket(8081);
while(listening)
{
Socket client = server.accept();
new ServerThread(client).start();
}
server.close();
}
}
ServerThread.java:
package exercise2;
import java.io.*;
import java.net.*;
public class ServerThread extends Thread
{
private Socket socket = null;
public ServerThread(Socket s)
{
this.socket = s;
}
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String message, reply = "";
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
System.out.println("test");
in.close();
out.close();
socket.close();
}
catch(IOException e)
{
System.err.println("error");
}
}
}
I've just started looking at HTTP etc. and have written a simple Java Client that uses URLConnection to send a URL to a server and pulls down the index.html page (as plain text).
Now I'm working on a simple server but I'm stuck at the first hurdle, (well maybe 2nd or 3rd), I can't get it to respond to the client properly.
Here is the reading in loop and it reads in the HTTP request fine, even from FF and IE etc:
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
The problem is that I don't know how to get it to respond anything useful. If I let it do what it is doing in the above code it sends "something" 6 times to my client (as there are 6 lines to the HTTP request) but nothing to FF/IE etc.
Also, it doesn't seem to break the loop ever as I added a System.out.println("test");
line to print after the loop but the server never seems to reach that point, should it? Should readLine() return null at the end of the first HTTP request?
I've been reading stuff on the sun and oracle websites but am still pretty stuck as to how this should work.
Thanks for your time,
Infinitifizz
EDIT: Oops, forgot to copy the code in.
Server.java:
package exercise2;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
boolean listening = true;
ServerSocket server = new ServerSocket(8081);
while(listening)
{
Socket client = server.accept();
new ServerThread(client).start();
}
server.close();
}
}
ServerThread.java:
package exercise2;
import java.io.*;
import java.net.*;
public class ServerThread extends Thread
{
private Socket socket = null;
public ServerThread(Socket s)
{
this.socket = s;
}
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String message, reply = "";
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
System.out.println("test");
in.close();
out.close();
socket.close();
}
catch(IOException e)
{
System.err.println("error");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在没有看到您的客户端代码的情况下,这是我对发生的情况的最佳猜测:
您的服务器可能在 readLine() 中阻塞,因为客户端已完成写入请求,但尚未关闭连接(因为它应该:客户端应该等待通过同一连接获得响应)。通常,HTTP 服务器在读取请求时解析请求:基于 this< /a>,您可以查找“\r\n\r\n”来划分标头的末尾,并在此时跳出读取循环以解析请求并对其进行响应。
Without seeing your client code, this is my best guess as to what's happening:
Your server is probably blocking in that readLine() because the client is done writing the request, but hasn't closed the connection (as it should: the client should wait around to get the response over that same connection). Typically, a HTTP server parses a request as it reads it: based on this, you can look for "\r\n\r\n" to demarcate the end of the header, and break out of your read loop at that point to parse the request and respond to it.
首先,将while循环中的条件更改为
<代码>
while(in.hasNextLine()) {
消息 = in.nextLine();
//等等......
其次,运行服务器时不需要退出 while 循环。您应该在 while 循环内对请求进行所有解析,并使用 if 语句来区分请求。唯一退出 while 循环的时间是连接应该关闭的时候,否则,
nextLine()
方法将阻塞,直到收到某些内容。First of all, change the condition in the while loop to
while(in.hasNextLine()) {
message = in.nextLine();
//etc....
Secondly, you don't need to exit out of the while loop while running a server. You should do all the parsing for requests inside the while loop, using if statements to distinguish the requests. The only time you would ever exit the while loop is when the connection should close, otherwise, the
nextLine()
method will block until something is received.