49-模拟实现一个简单的Tomcat

本文介绍如何使用Socket实现TCP服务器及客户端,深入解析HTTP协议,包括请求与响应过程,以及状态码含义。通过Java代码示例,展示如何模拟浏览器客户端和服务端,实现基本的HTTP通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tomcat:是一个动态的服务器,可以运行java程序
实现一个简单的Tomcat需要的技能点
1.Socket实现TCP服务器    实现tcp客户端
2.理解HTTPZ协议的传输,通信过程
3.javaSE其他内容整合一下

一、理解HTTP协议的相关内容
HTTP:Hypper Text Transfer Language超文本传输协议/控制协议
它是客户端和服务器之间的通信的规则
二、HTML:Hyper Text Markup Language超文本标记语言
(超文本:不仅仅是普通的文本,还可以放图片,视频,等等一系列的东西)

三、HTTP请求
1.请求行:请求的方式 请求的资源地址,协议的名称/版本
实例:GET http://www.baidu.cn/page/gsjj.shtml HTTP/1.1
2.请求头:
key: value 向服务器端传输客户端的相关信息和要求
①请求的服务器主机地址
Host:www.haidu.com
②客户端的相关信息 系统的信息 浏览器的版本等
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0)
Gecko/20100101 Firefox/66.0
③ 支持的数据格式
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
④支持的语言种类
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
⑤支持的数据压缩格式
Accept-Encoding: gzip, deflate
3.请求体
get请求:没有请求体
form表单的post:数据通过请求体传输
name=value&pwd=value…
一个正常的HTTP请求数据的组成:
请求头和请求体之间要有一个空行

GET http://www.bdqn.cn/page/gsjj.shtml HTTP/1.1
Host: www.bdqn.cn
Accept: text/html
Accept-Encoding: gzip, deflate
\r\n 空行
name=value&pwd=value....

四、
HTTP响应
1.响应行:协议名/协议版本 状态码 状态的描述信息
实例:HTTP/1.1 200 OK
经常出现的状态码以及它们的含义
1开头的:临时信息
2开头的:响应信息 成功响应:200 OK
3开头:重定向开关
302:重定向
304:执行缓冲内容
4开头:客户端的相应(错误相应)
400:不规范的请求 bad request
401:没有权限进行访问
404:资源找不到 NOT FOUND
5开头:服务器相应(错误响应)
500:服务器错误(一般都是我们自己的代码写错了) Internal Server Error
2.相应头:key: value
服务器标识:server:Nginx
时间:date: Sun, 21 Apr 2019 06:20:56 GMT
相应数据格式:content-type: text/html;charset=UTF-8
相应数据编码:content-encoding: gzip
3.相应体
相应数据
例如下代码






一个正常的HTTP响应数据的组成:
*记住在相应头和相应体之间要加上行空格 *

HTTP/1.1 200 OK回车符(\r) 换行符(\n)
server: nginx
date: Sun, 21 Apr 2019 06:20:56 GMT
content-type: text/html;charset=UTF-8
content-encoding: gzip
\r\n 空行
响应体数据

五、HTTP协议的特点
HTTP是基于TCP协议的连接,
它是灵活简单的一种传输协议
它也是无连接(无记忆)的协议
它是支持B/S和C/S架构
六、使用Socket模拟浏览器客户端,模拟服务端

1.模拟浏览器客户端(用java代码实现)

/**
 * 模拟实现浏览器客户端
 * @author Charles7c
 * 2019年4月21日 下午2:51:28
 */
public class TestClient {
	public static void main(String[] args) {
		Socket socket = null;
		OutputStream ops = null;
		InputStream ips = null;
		BufferedReader br = null;
		try {
			// 1.指定服务端的地址和端口
			socket = new Socket("www.bdqn.cn", 80);
			// 2.获取输出流  用来发送请求
			ops = socket.getOutputStream();
			// 获取输入流 用来接收响应
			ips = socket.getInputStream();
			// 3.发送HTTP协议的请求数据
			// 请求行
			ops.write("GET /page/gsjj.shtml HTTP/1.1\r\n".getBytes());
			// 请求头
			ops.write("Host: www.bdqn.cn\r\n".getBytes());
			ops.write("Accept: text/html\r\n".getBytes());
			ops.write("\r\n".getBytes());
			// 请求体(略)
			// 4.接收服务端的响应
			br = new BufferedReader(new InputStreamReader(ips));
			String line = null;
			while((line = br.readLine()) != null) {
				System.out.println(line);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				// 5.释放资源
				if(br != null) {
					br.close();
				}
				if(ips != null) {
					ips.close();
				}
				if(ops != null) {
					ops.close();
				}
				if(socket != null) {
					socket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}

2.模拟浏览器服务端

/**
 * 模拟服务端
 * @author Charles7c
 * 2019年4月21日 下午3:06:18
 */
public class TestServer {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket accept = null;
		InputStream ips = null;
		OutputStream ops = null;
		try {
			// 1.指定服务器端口
			serverSocket = new ServerSocket(8080);
			// 2.监听客户端请求
			accept = serverSocket.accept();
			// 3.获取输入流 用来接收客户端的请求数据
			ips = accept.getInputStream();
			// 获取输出流 用来给客户端响应数据
			ops = accept.getOutputStream();
			// 4.请求接收略,直接发起响应
			// 响应行
			ops.write("HTTP/1.1 200 OK\r\n".getBytes());
			// 响应头
			ops.write("server: tomcat\r\n".getBytes());
			ops.write("content-type: text/html;charset=UTF-8\r\n".getBytes());
			ops.write("\r\n".getBytes());
			// 响应体
			ops.write("<!DOCTYPE html>\r\n".getBytes());
			ops.write("<html>\r\n".getBytes());
			ops.write("<head>\r\n".getBytes());
			ops.write("<meta charset=\"UTF-8\">\r\n".getBytes());
			ops.write("<title>小杰瑞</title>\r\n".getBytes());
			ops.write("</head>\r\n".getBytes());
			ops.write("<body>\r\n".getBytes());
			ops.write("<h1>好嗨呦!</h1>\r\n".getBytes());
			ops.write("</body>\r\n".getBytes());
			ops.write("</html>\r\n".getBytes());
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			// 5.释放资源
			try {
				if(ops != null) {
					ops.close();
				}
				if(ips != null) {
					ips.close();
				}
				if(accept != null) {
					accept.close();
				}
				if(serverSocket != null) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值