在这次系列中,我们手写一个服务器,进行网络的进一步学习。
服务器发出信息,客户端进行接收。
package MyServer02;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;
/**
* 封装响应信息
* @author jh
* 封装响应信息,响应分成三个部分,Http版本信息,响应头,响应正文
*正文是由服务器端进行传入的
*其中,正文长度是非常重要的一个信息,正文长度被写在响应头,长度是二进制的长度
*HTTP协议的构成:
*1)Http协议版本 状态? 描述
*2)响应头
*3)响应正文
*/
public class Response {
private StringBuilder InfoHead;
private StringBuilder content;
public static final String CRLF="\r\n";
public static final String BLANK=" ";
public int len=0;
private BufferedWriter bw;
public Response() {
super();
len=0;
InfoHead=new StringBuilder();
content=new StringBuilder();
}
public Response(Socket server) {
this();
try {
bw=new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
CloseUtil.CloseAll(bw);
}
}
//私有的方法只供类内部调用
private void createInfoHead(int code) {
//1) HTTP协议版本、状态代码、描述
InfoHead.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
switch (code) {
case 200:
InfoHead.append("OK");
break;
case 404:
InfoHead.append("Not Found");
break;
case 505:
InfoHead.append("SEVER ERROR");
break;
}
InfoHead.append(CRLF);
//响应头(Response Head)
InfoHead.append("Server:bjsxt Server/0.0.1").append(CRLF);//固定格式,具体作用不大清楚
InfoHead.append("Date:").append(new Date()).append(CRLF);//时间
InfoHead.append("Content-type:text/html;charset=GBK").append(CRLF);//指定的编码集和解码集
//正文长度 :字节长度
InfoHead.append("Content-Length:").append(len).append(CRLF);
InfoHead.append(CRLF); //分隔符
//响应头和正文分别传输
}
//构建正文和回车
//return this方便追加内容
public Response println(String Info) {
content.append(Info).append("\n").append(CRLF);
len+=(Info+CRLF+"\n").getBytes().length;
return this;
}
public Response print(String Info) {
content.append(Info).append(CRLF);
len+=(Info+CRLF).getBytes().length;
return this;
}
public void pushtoclient(int code) {
if(InfoHead==null) {
code=500;
}
createInfoHead(code);
try {
bw.append(InfoHead.toString());
bw.append(content.toString());//BfferedWriter 的append和write方法
//
bw.flush();//最好使用输出流之后就加上flush()刷新
} catch (IOException e) {
// TODO Auto-generated catch block
CloseUtil.CloseAll(bw);
}
}
}
package MyServer02;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server01 {
private ServerSocket serverSocket=null;
public static void main(String[] args) {
Server01 server01=new Server01();
server01.start();
server01.stop();
}
public void start() {
try {
serverSocket=new ServerSocket(7777);
this.receive();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void receive() {
try {
Socket client=serverSocket.accept();
String meg=null;
StringBuilder sbBuilder=new StringBuilder();
BufferedReader bReader=new BufferedReader(new InputStreamReader(client.getInputStream()));
while((meg=bReader.readLine()).length()>0) {
sbBuilder.append(meg);
sbBuilder.append("\r\n");
if(meg==null) {
break;
}
}
String re=sbBuilder.toString().trim();
System.out.println(re);
Response response=new Response(client);
response.println("<html> <head><title>HTTP响应示例</title>");
response.println("</head><body>Hello Server!</body></html>");
response.pushtoclient(404);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stop() {
}
}
测试结果: