【JavaWeb】一个简单的Web浏览服务程序

大家天天开心!!!!!

文章目录

  • 前言
  • 一、一个简单的Web浏览服务程序
  • 二、对以上代码的解释:
    • 1.ServerSocket和Socket的生动比喻:
    • 2.网络通信的"公司大楼"模型
    • 重点概念详解
    • 常见端口号及其用途
  • 三、BufferedReader 和 FileReader 的角色
  • 总结

前言

在我们学习TomCat和Servlet之前,**我们要知道Tomcat其实就相互于一个Java程序,但是这个Java程序可以处理来自浏览器的Http请求。**下面我们就自己来编写一个"服务器"来接收和相应浏览器或客户端发送的请求。


提示:以下是本篇文章正文内容,下面案例可供参考

一、一个简单的Web浏览服务程序

下面是源代码:

java 复制代码
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class MyTomcat {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(9999)) {
            System.out.println("=====我的 web 服务在 9999 端口监听=====");

            while (!serverSocket.isClosed()) {
                try (Socket socket = serverSocket.accept();
                     OutputStream outputStream = socket.getOutputStream();
                     BufferedReader bufferedReader =
                             new BufferedReader(new FileReader("src/hello.html"))) {

                    // 发送HTTP响应头
                    String httpHeader = "HTTP/1.1 200 OK\r\n" +
                            "Content-Type: text/html; charset=utf-8\r\n" +
                            "\r\n";
                    outputStream.write(httpHeader.getBytes());

                    // 发送HTML内容
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        outputStream.write(line.getBytes());
                    }

                } catch (IOException e) {
                    System.out.println("处理客户端请求时出错: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            System.out.println("启动服务器失败: " + e.getMessage());
            // 检查端口是否被占用[1,3](@ref)
            System.out.println("请确认9999端口没有被其他程序占用");
        }
    }
}

二、对以上代码的解释:

首先先说明我这个是模拟的普通Web服务程序,让我们来看看Web服务器如何与浏览器"对话"是如何进行的

1.ServerSocket 和 Socket 的生动比喻:

你可以把整个网络通信过程想象成一个​​客服中心​​的工作流程:

组件 比喻 职责
​​ServerSocket​​ ​​客服总机​​ 它固定在公司的某个电话号码上(​​绑定端口​ ​,比如9999),只负责一件事:​​等待并接起打进来的电话​ ​(accept()方法)。它本身不处理具体业务。
​​Socket​​ ​​接通后的分机电话​​ 当总机 (ServerSocket) 接起一个来电后,它会为这个通话​​创建一条专用的分机线路​ ​(一个新的Socket对象)。客服通过这部​​分机电话​ ​与客户进行​​双向的、具体的沟通​ ​(数据交换)。​​服务器端和客户端各有一部这样的"电话"​​。

所以,在我的代码中:

    1. ServerSocket serverSocket = new ServerSocket(9999);就像是:​​开通了公司的客服总机,号码是9999​​。
    1. Socket socket = serverSocket.accept();就像是:​​总机接线员拿起听筒,等待并接起一个客户的来电。一旦电话接通,你就得到了一条和这位客户专用的通话线路(socket)​​。
    1. 客户端(浏览器)通过输入 localhost:9999来连接,就相当于:​​客户拨打你公司的总机号码​​

2.网络通信的"公司大楼"模型

概念 现实比喻 对应计算机概念
​​公司大楼​​ 一座有固定地址的办公楼 你的电脑(主机)
​​公司地址​​ 办公楼的具体街道门牌号 localhost或 127.0.0.1(本机地址)
​​客服总机号码​​ 公司对外公布的统一电话号码(如400-xxx) 端口号(如9999)
​​客服总机 (ServerSocket)​​ 前台的总机电话设备(绑定在公司号码上) ServerSocket serverSocket = new ServerSocket(9999);
​​客户来电​​ 外部客户拨打公司总机号码 浏览器访问 http://localhost:9999
​​分机电话 (Socket)​​ 总机转接给客服人员的专用分机 Socket socket = serverSocket.accept();
​​客服沟通​​ 客服通过分机与客户对话 通过 socket.getInputStream()/getOutputStream()读写数据

重点概念详解

  1. ​​localhost与 127.0.0.1​​:

    • • 它们就像你公司的​​两个别名​​,都指向同一栋大楼(你的电脑)。

    • • localhost是域名,127.0.0.1是IP地址,效果完全一样。就像"环球金融中心"和"浦东新区世纪大道100号"都指同一栋楼。

  2. ​​端口号(如9999)​​:

    • • 这相当于公司的​​分机号​​。一栋大楼(你的电脑)里可以有很多部门(应用程序),每个部门有自己专属的分机号(端口)。

    • • 常见端口:80(HTTP)、443(HTTPS)、3306(MySQL)... 你用的9999就像给测试部门临时开的分机。

  3. ​​ServerSocket​​:

    • • 它​​不是​ ​大楼本身,而是​​专门负责接听某个分机号(端口)的电话机​​。

    • • 当它 accept()时,就像前台拿起听筒:"您好,这里是9999号客服,请问有什么可以帮您?"

  4. ​​Socket​​:

    • • 这是​​接通后建立的专用通信通道​​。想象客服代表拿起分机:"王先生您好,我是您的专属客服小李,您的问题请讲..."

    • • 每个客户端连接都会创建一个新的 Socket对象(就像每个来电都转接给一个新的客服代表)。

端口是计算机网络中一个非常基础且重要的概念。它就像是计算机与外界通信的"门户"或"通道",用来区分一台计算机上不同的网络应用程序或服务

为了更具体地理解,这里有一个经典的比喻:

  • ​​IP 地址​ ​:相当于​​一栋大楼的地址​​(如:上海市浦东新区张江高科技园区博云路2号)。它唯一标识了网络上的某一台设备(计算机、服务器等)

    。

  • ​​端口号​ ​:相当于这栋大楼里​​每个房间的门牌号​​(如:301室、302室)。它唯一标识了这台设备上运行的不同网络程序或服务

    。

数据包通过IP地址找到目标计算机后,再通过端口号就能知道自己应该被哪个具体的应用程序(如浏览器、游戏、邮箱客户端)接收和处理,从而实现"多任务并行"和"精准投递"。

类别 端口号范围 用途 常见示例
​​知名端口​​ 0 - 1023 预留给最通用的网络服务,由国际组织IANA分配和管理。 ​​80​​: HTTP (网页浏览) ​​443​ ​: HTTPS (加密网页浏览) ​​21​ ​: FTP (文件传输) ​​22​ ​: SSH (安全远程登录) ​​25​​: SMTP (发送邮件)
​​注册端口​​ 1024 - 49151 松散地绑定于一些服务,许多用户或企业程序可以注册使用这些端口。 ​​3306​​: MySQL数据库 ​​3389​ ​: Windows远程桌面(RDP) ​​5432​​: PostgreSQL数据库

|---------------|---------------|-------------------------|----------------------------------------------|
| 动态/私有端口​​ | 49152 - 65535 | 通常由客户端程序临时使用,操作系统会动态分配。 | 当你用浏览器访问网站时,你的电脑就会用一个此范围内的端口去连接服务器的80或443端口。 |

常见端口号及其用途

了解一些常见端口号有助于你理解日常的网络活动和服务配置:

端口号 协议 用途简述
​​20/21​​ FTP ​​文件传输协议​​(数据/控制)
​​22​​ SSH ​​安全外壳协议​​,用于加密远程管理
​​23​​ Telnet ​​远程登录协议​​(明文传输,不安全)
​​53​​ DNS ​​域名系统​​,将域名解析为IP地址
​​67/68​​ DHCP ​​动态主机配置协议​​,自动分配IP地址
​​80​​ HTTP ​​超文本传输协议​​,用于网页浏览
​​110​​ POP3 ​​邮局协议版本3​​,用于接收邮件
​​143​​ IMAP ​​互联网消息访问协议​​,用于接收邮件
​​443​​ HTTPS ​​安全超文本传输协议​​,加密的网页浏览
​​3306​​ MySQL ​​MySQL数据库​​服务
​​3389​​ RDP ​​远程桌面协议​​,用于Windows远程控制

三、BufferedReader 和 FileReader 的角色

java 复制代码
BufferedReader bufferedReader = new BufferedReader(new FileReader("src/hello.html"));

这行代码做了两件事,涉及到两个类,它们是一种经典的​​"装饰器模式"​​的应用:

  1. ​​FileReader(文件读取器)​​:

    • • ​​它的角色是"基础工人"​​。它的任务很简单:负责打开文件,并按顺序一个字符一个字符地读取文件内容。

    • • ​​缺点​​:如果这个"工人"每读一个字符就要跑去文件那里一次(即频繁进行底层I/O操作),当文件很大时,效率会非常低。

  2. ​​BufferedReader(缓冲读取器)​​:

    • • ​​它的角色是"高效的调度员"​ ​。它自己不直接读文件,而是​​站在 FileReader这个"工人"身边指挥它​​。

    • • ​​工作原理​ ​:它会让 FileReader​​一次性多读一些内容​ ​(比如读取8KB的数据)到一个​​缓冲区​ ​(可以看作是一个"临时仓库")里。然后,当你调用 bufferedReader.readLine()时,它就不是慢吞吞地去文件里取,而是​​飞快地从"临时仓库"里把数据给你​​。

    • • ​​优点​ ​:通过​​减少直接访问文件(磁盘)的次数​​,大大提高了读取效率,尤其是在读取大文件时。

      它还提供了非常方便的 readLine()方法,可以直接读取一整行文本。

所以,new BufferedReader(new FileReader(...))这种套娃式的写法,意思就是:​​我想用一个高效的、带缓冲的读取器 (BufferedReader),来读取一个文件 (FileReader)​​。


总结

这就是一个简单的模拟的Web服务程序,大家可以自己试试模拟一下,了解浏览器和服务器是如何交互的,我会持续更新的,谢谢大家。

相关推荐
u0111026758 小时前
图片处理接口如何统一错误信息 前端提示与后端错误码设计
前端·状态模式
福兮说8 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
libokaifa8 小时前
把语音模型塞进手机:sherpa-onnx 在 Android 上的 ASR / TTS
前端
Joy T8 小时前
Spring AI 接入已有 Java 项目的三种架构设计
java·人工智能·springai·ai入门·chatclient·ai service·ai能力接入
deli0078 小时前
DLA 枝晶生长实测:5000 个粒子集体停摆之后,分形维数收敛到 1.70
前端
码事漫谈9 小时前
三步改掉 AI 味,附可直接复制的去 AI 味提示词
后端
杨运交9 小时前
[076][核心模块]构建优雅的Java异常处理框架:从错误码到全局异常处理
java·开发语言
IT_陈寒9 小时前
Redis卡顿的锅,这次真不是大key的错
前端·人工智能·后端
caoerzhong9 小时前
仓库数字化成熟度分级:JeeWMS 开源 Java 仓库管理系统如何支撑从可见到自治的四级跃迁
java·开源
可乐鸡翅yeah_9 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放