您的位置:首页 > 其它

创建一个本地端口为8001的服务器

2018-02-12 16:32 351 查看
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

class SocketHandler implements Runnable {

final static String CRLF = "\r\n";   // 1定义了HTTP头的换行符。

private Socket clientSocket;

public SocketHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}

public void handleSocket(Socket clientSocket) throws IOException {
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
);//字符输入流,用来接收客户端套接字传进来的字节流,再使用InputStreamReader转换成字符流
PrintWriter out = new PrintWriter(
new BufferedWriter( new OutputStreamWriter(clientSocket.getOutputStream())),
true
);//输出,用来将信息输出到客户端套接字;第二个参数true表示auto-flush

String requestHeader = "";
String s;

while ((s = in.readLine()) != null) {//当接收的信息为null时,不进入循环,而信息为“ ”时仍然进入循环,但是会break跳出。
s += CRLF;  // 2 很重要,默认情况下in.readLine的结果中`\r\n`被去掉了
requestHeader = requestHeader + s;
if (s.equals(CRLF)){ // 3 此处HTTP请求头我们都得到了;如果从请求头中判断有请求正文,则还需要继续获取数据
break;
}
}
System.out.println("客户端请求头:");
System.out.println(requestHeader);

String responseBody = "客户端的请求头是:\n"+requestHeader;

String responseHeader = "HTTP/1.0 200 OK\r\n" +
"Content-Type: text/plain; charset=UTF-8\r\n" +
"Content-Length: "+responseBody.getBytes().length+"\r\n" +
"\r\n";
// 4 问题来了:1、浏览器如何探测编码 2、浏览器受到content-length后会按照什么方式判断?汉字的个数?字节数?

System.out.println("响应头:");
System.out.println(responseHeader);

out.write(responseHeader);//向浏览器输出响应头
out.write(responseBody);//向浏览器输出响应体
out.flush();

out.close();
in.close();
clientSocket.close();

}

@Override
public void run() {
try {
handleSocket(clientSocket);
} catch(Exception ex) {
ex.printStackTrace();
}
}

}

public class MyHTTPServer {

public static void main(String[] args) throws Exception {

int port = 8001;//设置服务器端口
ServerSocket serverSocket = new ServerSocket(port);//实例化服务器对象
System.out.println("启动服务,绑定端口: " + port);

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(30);  // 5、创建一个30个线程的线程池

while (true) {  // 6、这个循环不停监听套接字连接,使用的SocketHandler处理连入的插座,而这个处理是放在线程池中的。
Socket clientSocket = serverSocket.accept();//通过服务器对象的accept方法来监听,将得到的客户端套接字定义为客户端套接字
System.out.println("新的连接"
+ clientSocket.getInetAddress() + ":" + clientSocket.getPort());//输出客户端的地址端口
try {
fixedThreadPool.execute(new SocketHandler(clientSocket));//执行实现了多线程的客户端的具体方法重写方法run()
} catch (Exception e) {
System.out.println(e);
}
}
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐