socket-server-http

目标:实现一个http协议的demo服务器

实现:启动一个ServerSocket,监听特定端口,然后浏览器请求,返回页面

 

代码实现:

package com.socket.bio.socket;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author xinchun.wang
 */
public class HttpServer {

	private static final int PORT = 9111;

	public static void main(String[] args) {
		System.out.println("服务器启动...\n");
		HttpServer server = new HttpServer();
		server.init();
	}

	public void init() {
		try {
			ServerSocket serverSocket = new ServerSocket(PORT);
			while (true) {
				// 一旦有堵塞, 则表示服务器与客户端获得了连接
				Socket client = serverSocket.accept();
				// 处理这次连接
				new HandlerThread(client);
			}
		} catch (Exception e) {
			System.out.println("服务器异常: " + e.getMessage());
		}
	}

	private class HandlerThread implements Runnable {
		private Socket socket;

		public HandlerThread(Socket client) {
			socket = client;
			new Thread(this).start();
		}

		public void run() {
			try {
				// 读取客户端数据
				byte[] data = new byte[1024*2];
				InputStream input = socket.getInputStream();
				int  ret = input.read(data);// 这里要注意和客户端输出流的写方法对应,否则会抛
				System.out.println("客户端发过来的内容:" + new String(data));

				while (ret>1024*2) {
					System.out.println("客户端发过来的内容:" + new String(data));
					ret = input.read(data);
				}

				if(!new String(data).contains("GET")){
					input.close();
					socket.close();
					return;
				}
				// 向客户端回复信息
				OutputStream out = socket.getOutputStream();
				// 发送键盘输入的一行
				
				StringBuilder result = new StringBuilder();
				result.append("HTTP/1.1 200 OK");
				result.append("\r\n");
				result.append("Server: Apache-Coyote/1.1");
				result.append("\r\n");
				result.append("Set-Cookie: JSESSIONID=613C816BEC2DB87DB7A043574B68AA57; Path=/");
				result.append("\r\n");
				result.append("Content-Type: text/html;charset=ISO-8859-1");
				result.append("\r\n");
				result.append("Content-Length: 293");
				result.append("\r\n");
				result.append("Date: Tue, 25 Apr 2017 02:58:49 GMT");
				result.append("\r\n");
				result.append("Connection: close");
				result.append("\r\n");
				
				//非常重要,换行下面是response的数据信息
				//如果没有下面这个换行,浏览器无法识别http的response报文
				result.append("\r\n");
				
				//数据body部分,也即浏览器上显示的东西
				result.append("<html>");
				result.append("hello world");
				result.append("</html>");
				System.out.println(result);
				out.write(result.toString().getBytes());

				out.close();
				input.close();
			} catch (Exception e) {
				System.out.println("服务器 run 异常: " + e.getMessage());
			} finally {
				if (socket != null) {
					try {
						socket.close();
					} catch (Exception e) {
						socket = null;
						System.out.println("服务端 finally 异常:" + e.getMessage());
					}
				}
			}
		}
	}
}

服务器端输出http请求的报文和返回的报文:

客户端发过来:
GET /index.html HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)
UA-CPU: AMD64
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:9111
Connection: Keep-Alive
Cookie: JSESSIONID=613C816BEC2DB87DB7A043574B68AA57

返回的报文:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=613C816BEC2DB87DB7A043574B68AA57; Path=/
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 293
Date: Tue, 25 Apr 2017 02:58:49 GMT
Connection: close
<html>hello world</html>

  

 

 浏览器请求效果:

 

 

猜你喜欢

转载自wangxinchun.iteye.com/blog/2371137