网络编程
# 网络编程
# InetAddress
- getByName (String host): 根据 ip 地址 / 主机名 返回一个 InetAddress 对象
- getHostName (): 返回主机名
- getHostAddress (): 以字符串形式返回 ip 地址
# IP
IPv4: 32bit (4 字节) 点分十进制表示法
IPV6: 128bit (8 字节) 冒分十六进制表示法
冒号后如果连为 0 可以省略 如 :0025 可以表示为:25
如果中间有多个连续的冒号可以简写为 2 个冒号 如: FF01:0:0:0:0:1101 写为 FF01::1101
# 端口
端口:应用程序在设备中唯一标识
端口号:两个字节表示的整数,取值范围 0 ~ 65535
# 协议
协议:连接和通信的规则被称为网络通信协议
# UDP 协议
- 用户数据报协议 (User Datagram Protocol)
- UDP 是面向无连接通信协议 连接快,有大小限制一次最多发生 64k, 数据不安全,易丢失数据
# TCP 协议
- 传输控制协议 (Transmission Control Protocol)
- TCP 协议是面向连接的通信协议 速度慢,没有大小限制,数据安全
# UDP 通信程序
# 发送端
- DatagramSocket () : 无参构造方法
- DatagramPacket (byte [] 数据数组,要传输数组的长度,目标地址对象,端口号): 带参构造方法 打包数据
- send (DatagramPacket 打包的数组): 发送数据
- close (): 关闭通信
// upd发送
DatagramSocket ds = new DatagramSocket();
//数据值
String s = "你好世界";
byte[] bytes = s.getBytes();
InetAddress byName = InetAddress.getByName("127.0.0.1");
int port = 10000;
// 打包数据
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, byName, port);
// 发送数据
ds.send(dp);
// 关闭
ds.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 接收端
- DatagramSocket (int 端口号) : 带参构造方法 接收数据的端口
- DatagramPacket ((byte [] 数据数组,要接收数组的长度): 带参构造方法 接收容器
- receive (DatagramPacket 接收容器): 接收数据 如果接收不数据会一直等待 (阻塞) 下面的代码不会执行
- getData (): 获取要接收到的数据 返回为一个字节数组
- getLength (): 获取要发送的数据的长度或接收到的数据的长度。
- close (): 关闭通信
// 接收端建立接收
DatagramSocket ds =new DatagramSocket(10000);
// 接收容器
byte[] bytes =new byte[1024];
DatagramPacket dp =new DatagramPacket(bytes,bytes.length);
// 接收数据
ds.receive(dp);
int lenth = dp.getLength();
System.out.println(new String(bytes,0,lenth));
// 关闭通信
ds.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 组播
上面 1 对 1 服务器对客户端 称为单播
组播又称多播 指特定某范围内客户端进行发送
组播地址:224.0.0.0 ~ 239.255.255.255 其中 244.0.0.0 ~ 224.0.0.255 为预留的组播地址
发送端 与 1 对 1 无异 注意 getByname 为组播地址
接收端 创建 MulticastSocket 对象
- joinGroup (InetAddress 对象): 把当前客户端加入到组播组中
MulticastSocket ms = new MulticastSocket(10000); ms.joinGroup(InetAddress.getByName("224.1.1.1")); byte[] bytes =new byte[1024]; DatagramPacket dp =new DatagramPacket(bytes,bytes.length); ms.receive(dp); int lenth = dp.getLength(); System.out.println(new String(bytes,0,lenth)); ms.close();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 广播
将数据发送到所有客户端
广播地址:255.255.255.255
- 发送端 与 1 对 1 无异 注意 getByname 为广播地址
- 接收端 与 1 对 1 无异 因为广播是无差别的发送
# TCP 通信程序
TCP 通信协议是一种可靠的网络协议,它在通信的两端各建立一个 Socket 对象
通信之前要确保连接已经建立
# 客户端
- Socket (string host, int port): 带参构造方法
- getOutputStream (): 获取一个 IO 流 返回一个 OutputStream 对象
- write (): 写入 (传输) 数据
- close (): 在关闭流的时候 会给对方发送一个结束标记动作
Socket sk =new Socket("127.0.0.1",10000);
OutputStream outputStream = sk.getOutputStream();
outputStream.write("hello".getBytes(StandardCharsets.UTF_8));
outputStream.close();
sk.close();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 服务端
- ServerSocket (int port) : 带参构造方法
- accept (): 返回一个 Socket 对象 会有阻塞现象
- getInputStream (): 获取输入流
- read (): 读取流中的数据 返回值为一个 int 会有阻塞现象
ServerSocket ss =new ServerSocket(10000);
Socket accept = ss.accept();
InputStream inputStream = accept.getInputStream();
int b;
while ((b = inputStream.read()) != -1){
System.out.println((char) b);
}
accept.close();
ss.close();
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 原理
- accept 方法是阻塞的,作用是等待客户端连接
- 客服端创建对象并连接服务器,此时是通过三次握手协议保证跟服务器之间的连接
- 针对客户端来讲,是往外写,所以是输出流 针对服务器来讲,是往里读,所以是输入流
- read 方法也是阻塞
- 在关闭流的时候,还多了一个往服务器写结束标记的动作
- 最后一步断开连接,通过四次挥手协议保证连接终止
# 三次握手

- 向服务器发出连接请求
- 服务器向客户端返回一个响应
- 客户端再次向服务器发出确认信息
# 四次挥手

- 客户端向服务器发出取消请求
- 服务器向客户端返回一个响应
- 服务器向客户端发出确认取消信息
- 客户端再次发送确认消息
# UUID
java 提供 UUID 类 可以方便的生成 uuid
- randomUUID (): 伪随机 返回一个 UUID 对象
- toString (): 将 UUID 对象转成 String
编辑 (opens new window)
上次更新: 2023/12/06, 01:31:48