【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.网络通信的"公司大楼"模型

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

重点概念详解

  1. localhost127.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服务程序,大家可以自己试试模拟一下,了解浏览器和服务器是如何交互的,我会持续更新的,谢谢大家。

相关推荐
柯南二号3 小时前
【大前端】 断点续传 + 分片上传(大文件上传优化) 的前端示例
前端
前端小超超3 小时前
如何配置capacitor 打包的安卓app固定竖屏展示?
android·前端·gitee
用户298698530143 小时前
如何在 C# 中用表格替换 Word 文档中的文本?
后端
B612 little star king3 小时前
力扣29. 两数相除题解
java·算法·leetcode
野犬寒鸦3 小时前
力扣hot100:环形链表(快慢指针法)(141)
java·数据结构·算法·leetcode·面试·职场和发展
xiaopengbc3 小时前
在Webpack中,如何在不同环境中使用不同的API地址?
前端·webpack·node.js
上官浩仁3 小时前
springboot synchronized 本地锁入门与实战
java·spring boot·spring
前端AK君3 小时前
React中台系统如何嵌入到业务系统中
前端
Gogo8163 小时前
java与node.js对比
java·node.js