网络通信介绍(重点)
什么是网络通信?
- 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)
- 比如:微信聊天、LOL游戏、京东、淘宝网站的访问
基本的通信架构
基本的通信架构有2种形式:CS架构( Client客户端/Server服务端 ) 、 BS架构(Browser浏览器/Server服务端)
![image-20240414214900168](https://img-blog.csdnimg.cn/img_convert/ab9df96efa7490786a6f72af01fe9a2c.png)
Browser-Server(BS)
无论是CS架构,还是BS架构的软件都必须依赖网络通信!
网络通信三要素(重点)
- 网络通信三要素
- IP: 设备在网络中的地址,是唯一的标识。
- 端口: 应用程序在设备中唯一的标识
- 协议: 连接和数据在网络中传输的规则。(双方收发消息的标准)
IP地址
- **IP(Internet Protocol):**全称”互联网协议地址”,是分配给上网设备的唯一标志。
- IP地址有两种形式:IPv4、IPv6
IPV4地址
32bit → 11000000 10101000 00000001 01000010 → (点分十进制表示法) → 192.168.1.1
IPV6地址
- IPv6:共128位,号称可以为地球每一粒沙子编号。
- IPv6分成8段表示,每段每四位编码成一个十六进制位表示, 数之间用冒号(:)分开。
2001:0db8:0000:0023:0008:0800:200c:417a
公网IP, 内网IP
- 公网IP:是可以连接互联网的IP地址
- 内网IP:也叫局域网IP,只能组织机构内部使用
- 192.168. 开头的就是常见的局域网地址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用
特殊IP地址
- 127.0.0.1、localhost:代表本机IP,只会寻找当前所在的主机
IP常用命令
- ipconfig:查看本机IP地址
- ping IP地址:检查网络是否连通
IP域名
![]()
InetAddress
代表IP地址
常用方法
名称 | 说明 |
---|---|
public static InetAddress getLocalHost() | 获取本机IP,会以一个inetAddress的对象返回 |
public static InetAddress getByName(String host) | 根据ip地址或者域名,返回一个inetAddress对象 |
public String getHostName() | 获取该ip地址对象对应的主机名 |
public String getHostAddress() | 获取该ip地址对象中的ip地址信息 |
public boolean isReachable(int timeout) | 在指定毫秒内,判断主机与该ip对应的主机是否能连通 |
总结
1、IP地址是做什么的,具体有几种
- 定位网络上的设备的,有IPv4 , IPv6
2、公网ip和内网ip的区别是什么?
- 公网ip可以全网访问,内网ip只能局域网内部访问
3、如何查看本机IP地址,如何看是否与对方互通
- ipconfig
- ping 192.168.10.23
4、本机IP是谁?
- 127.0.0.1或者是localhost
IP地址的代表类是谁?
- InetAddress类
如何获取本机IP对象
- public static InetAddress getLocalHost()
如何判断与该IP地址对象是否互通?
- public boolean isReachable(int timeout)
端口号
端口
- 标记正在计算机设备上运行的应用程序的一个数字,范围是 0~65535。
- 唯一标识正在计算机设备上运行的进程(程序)
分类
- 周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用 80,FTP占用21)
- **注册端口:**1024~49151,分配给用户进程或某些应用程序。
- 动态端口:49152到65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。
注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。
通信协议(重点)
1、通信协议是什么?
- 网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。
开放式网络互联标准:OSI网络参考模型
- OSI网络参考模型:全球网络互联标准
- TCP/IP网络模型:事实上的国际标准
OSI网络参考模型 | TCP/IP网络模型 | 各层对应 | 面向操作 |
---|---|---|---|
应用层 表示层 会话层 | 应用层 | HTTP、FTP、SMTP… | 应用程序需要关注的:浏览器,邮箱。程序员一般在这一层开发 |
传输层 | 传输层 | UDP、TCP… | 选择使用的TCP , UDP协议 |
网络层 | 网络层 | IP… | 封装源和目标IP |
数据链路层 物理层 | 数据链路层+ 物理 | 比特流… | 物理设备中传输 |
传输层的2个通信协议
- UDP(User Datagram Protocol):用户数据报协议
- TCP(Transmission Control Protocol) :传输控制协议
UDP协议(通信效率高! 语音通话 视频直播)
- 特点:无连接、不可靠通信。
- 不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内)等。
- 发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的 。
TCP协议: (通信效率相对不高,网页 文件下载 支付)
- 特点:面向连接、可靠通信。
- TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。
- TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。
TCP协议:三次握手建立可靠连接( 背诵 )
可靠连接:确定通信双方,收发消息都是正常无问题的!
传输数据进行确认, 以保证数据传输可靠性
![image-20240423110306614](https://img-blog.csdnimg.cn/img_convert/6e79823b0306c443135c5958229ca0bd.png)
TCP协议:四次挥手断开连接
目的: 确保双方数据的收发都已完成
![image-20240415083445506](https://img-blog.csdnimg.cn/img_convert/8c354a9e2272974bd4d33cd02d429e86.png)
UDP通信
快速入门
UDP通信
- 特点:无连接、不可靠通信
- 不事先建立连接;发送端每次把要发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包,发出去就不管了
- Java提供了一个java.net.DatagramSocket类来实现UDP通信
DatagramSocket: 用于创建客户端、服务端
构造器 | 说明 |
---|---|
public DatagramSocket() | 创建客户端的Socket对象, 系统会随机分配一个端口号 |
public DatagramSocket(int port) | 创建服务端的Socket对象, 并指定端口号 |
方法 | 说明 |
---|---|
public void send(DatagramPacket dp) | 发送数据包 |
public void receive(DatagramPacket p) | 使用数据包接收数据 |
DatagramPacket:创建数据包
构造器 | 说明 |
---|---|
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 创建发出去的数据包对象 |
public DatagramPacket(byte[] buf, int length) | 创建用来接收数据的数据包 |
方法 | 说明 |
---|---|
public int getLength() | 获取数据包,实际接收到的字节个数 |
使用UDP通信实现:发送消息(步骤)
客户端实现步骤
- 创建DatagramSocket对象(客户端对象) ➨ 扔韭菜的人
- 创建DatagramPacket对象封装需要发送的数据(数据包对象) ➨ 韭菜盘子
- 使用DatagramSocket对象的send方法,传入DatagramPacket对象 ➨ 开始抛出韭菜
- 释放资源
使用UDP通信实现:接收消息(步骤)
服务端实现步骤
- 创建DatagramSocket对象并指定端口(服务端对象) ➨ 接韭菜的人
- 创建DatagramPacket对象接收数据(数据包对象) ➨ 韭菜盘子
- 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ➨ 开始接收韭菜
- 打印结果
- 释放资源
总结
- 数据包对象是哪个?
- DatagramPacket
- 如何发送、接收数据包
- 使用DatagramSocket的如下方法:
- public void send(DatagramPacket dp):发送数据包
- public void receive(DatagramPacket dp) :接收数据包
多发多收
客户端可以反复发送数据(步骤)
客户端实现步骤
- 创建DatagramSocket对象(发送端对象) ➨ 扔韭菜的人
- 使用while死循环不断的接收用户的数据输入,如果用户输入的exit则退出程序
- 如果用户输入的不是exit, 把数据封装成DatagramPacket ➨ 韭菜盘子
- 使用DatagramSocket对象的send方法将数据包对象进行发送 ➨ 开始抛出韭菜
- 释放资源
接收端可以反复接收数据(步骤)
接收端实现步骤
- 创建DatagramSocket对象并指定端口(接收端对象) ➨ 接韭菜的人
- 创建DatagramPacket对象接收数据(数据包对象) ➨ 韭菜盘子
- 使用DatagramSocket对象的receive方法传入DatagramPacket对象 ➨ 开始接收韭菜
- 使用while死循环不断的进行第3步
总结
UDP的接收端为什么可以接收很多发送端的消息?
- 接收端只负责接收数据包,无所谓是哪个发送端的数据包。
广播、组播
- 如何实现广播,具体怎么操作?
- 发送端目的IP使用广播IP: 255.255.255.255 9999。
- 所在网段的其他主机对应了端口(9999)即可接收消息。
- 如何实现组播,具体怎么操作?
- 发送端目的IP使用组播IP,且指定端口。
- 所在网段的其他主机注册了该组播IP和对应端口即可接收消息。
TCP通信
快速入门
TCP通信
- 特点:面向连接、可靠通信。
- 通信双方事先会采用“三次握手”方式建立可靠连接,实现端到端的通信;底层能保证数据成功传给服务端。
- Java提供了一个java.net.Socket类来实现TCP通信。
![image-20240415090935710](https://img-blog.csdnimg.cn/img_convert/a325d10abd06749e7edb19cb26072a75.png)
TCP通信之-客户端开发
- 客户端程序就是通过java.net包下的Socket类来实现的。
构造器 | 说明 |
---|---|
public Socket(String host , int port) | 根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket |
方法 | 说明 |
---|---|
public OutputStream getOutputStream() | 获得字节输出流对象 |
public InputStream getInputStream() | 获得字节输入流对象 |
客户端发送消息(步骤)
客户端实现步骤
- 创建客户端的Socket对象,请求与服务端的连接
- 使用socket对象调用getOutputStream()方法得到字节输出流
- 使用字节输出流完成数据的发送
- 释放资源:关闭socket管道
TCP通信-服务端程序的开发
服务端是通过java.net包下的ServerSocket类来实现的。
ServerSocket
构造器 | 说明 |
---|---|
public ServerSocket(int port) | 为服务端程序注册端口 |
方法 | 说明 |
---|---|
public Socket accept() | 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象 |
服务端实现接收消息(步骤)
服务端实现步骤
- 创建ServerSocket对象,注册服务端端口。
- 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象。
- 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
- 释放资源:关闭socket管道
总结
-
TCP通信的客户端的代表类是谁?
- Socket类
- public Socket(String host , int port)
-
TCP通信如何使用Socket管道发送、接收数据。
- OutputStream getOutputStream():获得字节输出流对象(发)
- InputStream getInputStream():获得字节输入流对象(收)
-
TCP通信服务端用的代表类?
- ServerSocket类,注册端口。
- 调用accept()方法阻塞等待接收客户端连接。得到Socket对象。
-
TCP通信的基本原理?
- 客户端怎么发,服务端就应该怎么收。
- 客户端如果没有消息,服务端会进入阻塞等待。
- Socket一方关闭或者出现异常、对方Socket也会失效或者出错。
多发多收消息
使用TCP通信实现:多发多收消息(案例)
- 使用TCP通信实现:多发多收消息。
- 客户端使用死循环,让用户不断输入消息。
- 服务端也使用死循环,控制服务端收完消息,继续等待接收下一个消息。
- 现在服务端为什么不可以同时接收多个客户端的消息。
- 目前服务端是单线程的,每次只能处理一个客户端的消息。
多客户端通信(重点)
目前我们开发的服务端程序,是否可以支持与多个客户端同时通信 ?
- 不可以的。
- 因为服务端现在只有一个主线程,只能处理一个客户端的消息。
TCP通信-支持与多个客户端同时通信
![image-20240415100710817](https://img-blog.csdnimg.cn/img_convert/736d140198c51d3154c9c2778d4ba13b.png)
**本次是如何实现服务端接收多个客户端的消息的? **
- 主线程定义了循环负责接收客户端Socket管道连接
- 每接收到一个Socket通信管道后分配一个独立的线程负责处理它。
实战案例-模拟BS系统(了解)
BS架构的基本原理
http://服务器IP:服务器端口 : http://127.0.0.1:8080
![]()
注意:服务器必须给浏览器响应HTTP协议规定的数据格式,否则浏览器不识别返回的数据。
HTTP协议规定:响应给浏览器的数据格式必须满足如下格式(简单了解)
![]()
BS架构的基本原理是什么?
- 客户端使用浏览器发起请求(不需要开发客户端)
- 服务端必须按照HTTP协议响应数据。
使用线程池优化
- 本次使用线程池的优势在哪里?
- 服务端可以复用线程处理多个客户端,可以避免系统瘫痪。
- 适合客户端通信时长较短的场景。
即时通信
- 即时通信是什么含义,要实现怎么样的设计?
- 即时通信,是指一个客户端的消息发出去,其他客户端可以接收到
- 即时通信需要进行端口转发的设计思想。
- 服务端需要把在线的Socket管道存储起来
- 一旦收到一个消息要推送给其他管道