# 请求响应封装
* 目的:
* 所学知识的综合运用。
* javaweb学习过渡。
# 一 单机程序与网络程序
* 什么是程序
* 程序是一组静态的代码
* 逻辑
* 数据
* 运行起来的程序 — 进程 (分配内存 + 执行单元-线程)
* 单机程序
* 逻辑的执行和数据的处理,都是在一台主机上执行的。
* 数据存储在内存或磁盘
* 网络程序
* 逻辑的执行和数据的处理,需要在多台主机之间完成。
* 此时需要基于网络 (局域网, 广域网)
* **注意1:**
* 对于网络程序而言,数据存储在哪不重要。
* **注意2:**
* 一台主机上的两个程序交互,也类似于网络程序。url localhost:3306
* 未来我们使用java编写的都是web程序,是一种网络程序,网络程序之间的交互思想就是请求-响应。
# 二 网络编程
## 1 客户端程序与服务端程序
* 在网络编程中,需要至少两个程序配合完成应用。
* 一个是客户端程序,一个是服务端程序
* 两类程序没有明确的物理定义,一般都是逻辑定义。
* 客户端主动去连接服务端。
* 一旦连接成功,谁主动交互就无所谓了。
* 接下来我们会用java编写客户端和服务端。
## 2 IP
* 在网络环境中,每一个主机都会拥有一个唯一的网络标识:ip
* 在网络编程中,可以通过ip找到我们需要交互的那个程序所在的主机。
* ipv4 : 32bit 平均分成4份。 每一份8bit 0-255
* ipv6:128bit 分成8组,每组使4个十六进制表示
* 扩展:
* 本机两个程序之间的数据交互,也会通过网卡。就会基于ip找到程序所在的主机
* 有以下3种ip找到本机
* 127.0.0.1
* localhost
* 192.168.30.103
## 3 port
* 端口 : 就是一个程序与外部数据库交互的入口
* 所以找到了程序所在的主机,在主机上找到了程序的端口,就可以和这个程序数据交互了。
* 数据交互使用的是物理端口,与指定的程序数据交互,使用的是逻辑端口
* 逻辑端口使用数字表示 范围 0~65535
* 每个程序启动时都会拥有一个端口号
* 这个端口号有可能是我们程序提供的,也可能是系统分配的。
* 如果分配的端口被其他程序占用,则当前程序无法启动。
* 系统启动时,一些系统程序会占用0-1024之间的端口号, 我们手动分配时应尽量避免这些端口号。
## 4 socket
* 套接字
* 可以实现两个主机程序之间的网络连接(交互)
* 网络中两个程序的数据交互(传输),是基于网络模型中的传输层
* 有两种传输协议
* TCP/IP 数据的安全交互
* UDP 数据传输是不安全,适合广播的形式传输数据。
* socket就是TCP和UDP基础上的一个抽象
<img src="01.png" alt="1678887985802" style="zoom:50%;" />
* IO 使用socket实现了两个网络程序的联通,最终的数据库交互就是IO
## 5 实现网络程序
* 创建客户端程序和服务端程序,提供main方法(启动方法)
* 两个程序需要通过socket对象来实现网络通讯
* 其中服务端程序 需要创建ServletSocket对象,并等待客户端的连接
```java
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(6666);
System.out.println("----启动服务器----");
//以阻塞的形式等待客户端连接
Socket link = server.accept();
System.out.println("连接上了一个客户端");
//...
}
```
* 客户端程序需要创建Socket对象,连接服务端程序
```java
public static void main(String[] args) throws IOException {
Socket client = new Socket("localhost",6666);
//...向服务器发送信息
//放置客户端中途停止, 服务端出现连接被拒绝的错误。
while(true);
}
```
* 一旦双方连接上,就准备数据交互了。 数据交互使用IO技术。 如何获得IO呢? 通过socket对象
* socket常用api
```java
socket.getInputStream();
socket.getOutputStream();
socket.getInetAddress(); 获得另一方的ip地址
```
* **注意:网路通讯时数据读取结束问题**
* 回忆:文件读取时,如何判断文件内容读取完毕呢?
```java
while(true){
int b = is.read();
if(b == -1)
break ;
//处理
}
while(is.available() > 0){
int b = is.read();
//处理
}
```
* 在网络通讯时,上述两种方式都存在问题
* 起初客户端还没有写数据的时候,服务端的`is.available()`就是0,所以无法确定是没有数据来,还是数据读取完毕。
* 当客户端(逻辑上)输出完成,服务端读取完成后,服务端认为客户端可能还一会还会传递数据,所以会处于等待状态(阻塞), **怎么解决这个问题?**
* 客户端关闭输出流,确保输出结束了,此时服务端可以读取到-1 `link.shutdownOutput();`
* 给以结束标记。`os.write("over")`
# 三 C/S与B/S网络结构
* 网络程序主要有两种设计结构
## 1 C/S
* 客户端/服务端程序
* 一个完整程序的执行,需要由两部分配置来完成
* 客户端程序多用来做界面展示和操作 UI
* 服务端主要完成具体的功能操作。
* 对于c/s结构而言, 客户端有时也会完成一些功能操作和数据存储处理。
* 对于c/s结构中的两个部分属于一个完整的程序(属于一个团队开发)。
* QQ客户端 和 QQ服务端。
* 特点:
* 交互性强,响应速度快,安全性高,个性化强。
* 用户群体固定
* 兼容性差,开发和维护的成本高。
* 更新时需要客户端与服务端同时更新(用户体验差)
* java可以开发c/s结构的程序,但java更适合B/S程序的开发。
## 2 B/S
* browser / web server
* 一个完整的B/S结构程序,由三部分组成
* 浏览器程序,服务器程序,业务程序
* 三部分程序分别由三个团队独立开发
* 业务程序才是我们B/S结构程序的主题。淘宝,京东,当当,。。。。
* 我们主要使用的是**业务程序** 。 业务程序提供了操作功能和操作界面
* 未来更新升级时,一次升级即可。
* 业务程序中只提供了界面,但没有提供界面的展示能力(缺少客户端)
* **浏览器程序**可以用来展示界面供用户操作
* 理论上来讲,浏览器可以展示淘宝界面,京东界面...
* 问题是,浏览器平时什么就知道淘宝要展示什么样的界面呢? 京东要展示什么样的界面呢?
浏览器怎么认识淘宝程序编写(提供)界面的代码 ?
* 这里就需要两者之间制定一些规则/规范/协议 (http)
* **服务器**的出现,可以简化浏览器与业务程序之间的规范处理
* 没有服务器,每一个业务程序都需要了解交互规范
* 有了服务器,只需要服务器了解交互规范即可,业务程序可以更专注业务功能和界面设计。
* 问题来了,服务器和业务程序之间是如何交互的,遵守了什么规范呢?
* 遵守java语法规范。 通过创建对象,调用方法来实现交互。
* 服务器程序和业务程序毕竟是两个程序,为什么可以直接通过java语法调用呢?
* 原因时,执行的时,两个程序合二为一了 业务程序->服务器(部署),服务器->业务程序(内嵌)
<img src="02.png" alt="1678973552531" style