我正在尝试开发一个允许我在线程上运行套接字的类,并且它随时允许我通过它发送数据,以及在数据到达时接收通知。它应该假设没有诸如仅在首先发送消息之后接收消息等的事情,等等。 由于某种原因,以下代码仅打印第一个请求的响应:
public static void main(String[] args) throws IOException {
TCPClient client = new TCPClient(new TCPClientObserver());
client.connect("www.microsoft.com", 80);
sleep(1000);
client.send("HTTP GET");
sleep(5000);
client.send("XYZ");
}
印刷
echo: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
echo: <HTML><HEAD><TITLE>Bad Request</TITLE>
echo: <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
echo: <BODY><h2>Bad Request - Invalid URL</h2>
echo: <hr><p>HTTP Error 400. The request URL is invalid.</p>
echo: </BODY></HTML>
这是套接字的核心逻辑:
echoSocket = new Socket("www.microsoft.com", 80);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
while (true) {
String response = in.readLine();
if (response != null)
System.out.println("echo: " + response);
}
我猜问题出在我的循环中?
我的应用程序的完整测试代码可以在这里看到: http://codepad.org/bmHwct35
由于
答案 0 :(得分:2)
问题不在于循环,而是您发送的第一个请求。 “HTTP GET”是无效请求,服务器应响应“400 Bad request”,然后关闭连接。这就是为什么你没有得到第二条消息的回应。尝试有效的HTTP请求,例如“GET / HTTP / 1.1 \ r \ nHost:www.microsoft.com \ r \ n \ r \ n”而不是。默认情况下,HTTP 1.1连接保持活动状态,因此您可以发送多个连接并接收后续响应。
答案 1 :(得分:1)
问题是HTTP服务器与HTTP协议通信,而您的客户端代码没有正确地协商协议。相反,它打开一个普通的套接字并编写似乎基于猜测的随机内容。
HTTP协议在this document中指定。如果你阅读它,你会发现你正在做的事情与客户应该做的事情完全不同。
我建议您不要尝试以这种方式实现客户端。从头开始实现HTTP协议的客户端工作太多了......世界上还不需要另一个flakey HTTP客户端。使用标准URL / HttpURLConnection API,或使用第三方HTTP客户端库。
在您的情况下,400响应很可能是发送格式错误的请求的结果。 HTTP GET请求(实际上是任何HTTP请求)应该包含第一行中的目标URL。阅读规范。
答案 2 :(得分:1)
您发送的第一个请求是无效的,在回复后服务器将关闭连接。在您的代码中,您将被卡在while (true)
循环中,因为当连接/流关闭(到达流末尾)时,您将从null
返回readLine
。
while (true) { // <-- never terminates
String response = in.readLine();
if (response != null) // <- now null all the time
System.out.println("echo: " + response);
}
答案 3 :(得分:1)
假设HTTP 400是您所期望的,如果readLine()返回null,则需要中断循环。这通常是这样写的:
while ((line = in.readLine()) != null)
{
// ...
}