cod*_*rix 3 java sockets network-programming http
我使用java创建了以下测试服务器:
import java.io.*;
import java.net.*;
class tcpServer{
public static void main(String args[]){
ServerSocket s = null;
try{
s = new ServerSocket(7896);
//right now the stream is open.
while(true){
Socket clientSocket = s.accept();
Connection c = new Connection(clientSocket);
//now the connection is established
}
}catch(IOException e){
System.out.println("Unable to read: " + e.getMessage());
}
}
}
class Connection extends Thread{
Socket clientSocket;
BufferedReader din;
OutputStreamWriter outWriter;
public Connection(Socket clientSocket){
try{
this.clientSocket = clientSocket;
din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "ASCII"));
outWriter = new OutputStreamWriter(clientSocket.getOutputStream());
this.start();
}catch(IOException e){
System.out.println("Connection: " + e.getMessage());
}
}
public void run(){
try{
String line = null;
while((line = din.readLine())!=null){
System.out.println("Read" + line);
if(line.length()==0)
break;
}
//here write the content type etc details:
System.out.println("Someone connected: " + clientSocket);
outWriter.write("HTTP/1.1 200 OK\r\n");
outWriter.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
outWriter.write("Expires: -1\r\n");
outWriter.write("Cache-Control: private, max-age=0\r\n");
outWriter.write("Content-type: text/html\r\n");
outWriter.write("Server: vinit\r\n");
outWriter.write("X-XSS-Protection: 1; mode=block\r\n");
outWriter.write("<html><head><title>Hello</title></head><body>Hello world from my server</body></html>\r\n");
}catch(EOFException e){
System.out.println("EOF: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO at run: " + e.getMessage());
}finally{
try{
outWriter.close();
clientSocket.close();
}catch(IOException e){
System.out.println("Unable to close the socket");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我希望这台服务器响应我的浏览器.这就是我给url的原因:http://localhost:7896
因此我在服务器端收到:
ReadGET / HTTP/1.1
ReadHost: localhost:7896
ReadConnection: keep-alive
ReadCache-Control: max-age=0
ReadAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
ReadUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
ReadAccept-Encoding: gzip,deflate,sdch
ReadAccept-Language: en-US,en;q=0.8
ReadAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
ReadCookie: test_cookie=test cookie
Read
Someone connected: Socket[addr=/0:0:0:0:0:0:0:1,port=36651,localport=7896]
Run Code Online (Sandbox Code Playgroud)
我浏览器和源代码的空白屏幕也是空白.在谷歌浏览器中.
所以任何人都可以告诉我哪里错了.实际上我是这个新手.所以请纠正我.
提前致谢
你几乎肯定不想DataOutputStream在响应中使用 - writeUTF当然也不会做你想要的.DataOutputStream基本上是为二进制协议设计的 - 并且writeUTF写了一个长度为前缀的UTF-8字符串,而HTTP只是想要CRLF终止的ASCII文本行.
您希望一次写出一行代码 - 因此OutputStreamWriter在套接字输出流周围创建一个,然后写入:
writer.write("HTTP/1.1 200 OK\r\n");
writer.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
Run Code Online (Sandbox Code Playgroud)
等等
您可能希望编写自己的writeLine方法来写出包括最后CRLF的行(不要使用系统默认行终止符),以使代码更清晰.
在标题和正文之间添加一个空行,然后你应该是合理的形状.
编辑:另外两个变化:
首先,您应该阅读客户端的请求.例如,更改din为a BufferedReader,并将其初始化为:
din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
"ASCII"));
Run Code Online (Sandbox Code Playgroud)
然后在开始编写输出之前,请按以下方式读取请求:
String line;
while ((line = din.readLine()) != null) {
System.out.println("Read " + line);
if (line.length() == 0) {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:如评论中所述,这不适合完整的HTTP服务器,因为它不能很好地处理二进制PUT/POST数据(它可能会将数据读入其缓冲区,这意味着您无法将其读取为来自流的二进制数据).这对测试应用程序来说很好.
最后,您还应关闭输出编写器或至少刷新它 - 否则它可能正在缓冲数据.
进行这些更改后,您的代码对我有用.