使用 UDP 的 Socket API 实现服务端
# 什么是 Socket(套接字)
概念 : Socket 套接字是由系统提供于网络通信的技术, 是基于 TCP/IP 协议的网络通信的基本操作党员, 基于 Socket 套接字的网络程序开发就是网络编程
要进行网络通信, 需要有一个 socket 对象, 一个 socket 对象对应着一个 socket 文件, 这个文件在 网卡上而不是硬盘上, 所以有了 sokcet 对象才能通过操作内存来操作网卡 在 socket 文件中写数据相当于通过网卡发送数据, 在 socket 文件中读数据相当于通过网卡接收数据
Socket API 分为两类 : 基于 TCP 协议的 API , 和基于 UDP 协议的 API
# TCP 协议和 UDP 协议的区别和特点
# 基于 UDP 协议的 Socket API
# 服务端
因为UDP没有创建连接,数据包也是一次收发一个,所以没有流的概念。
在服务器端,使用UDP也需要监听指定的端口。Java提供了DatagramSocket
来实现这个功能,代码如下:
// 1,从客户端读取请求数据
DatagramSocket socket = new DatagramSocket(port);
// 数据缓冲区:
byte[] buffer = new byte[10240];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
//长度是缓冲区大小
byte[] data = packet.getData();
//实际报文大小
byte[] dataBytes = new byte[packet.getLength()];
System.arraycopy(data,packet.getOffset(),dataBytes,0,packet.getLength());
//转成16进制
String message = bytesToHexString(dataBytes);
//2.业务处理
// 3,把响应发送给客户端
String responseString = "OK";
packet.setData(responseString.getBytes());
socket.send(packet);
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
需要注意的是:DatagramPacket.getData()反映了DatagramPacket对应缓冲区中的新接收到的数据和未被覆盖的旧数据,当我们使用DatagramPacket来处理新接收到的数据时,就容易同时触及到旧数据导致混乱,而DatagramPacket.getLength()反映的是刚刚接收到的数据的长度。
# 客户端
DatagramSocket ds = new DatagramSocket();
ds.setSoTimeout(1000);
ds.connect(InetAddress.getByName("localhost"), 1234); // 连接指定服务器和端口
// 发送:
byte[] data = hexStringToByteArray("68");
DatagramPacket packet = new DatagramPacket(data, data.length);
ds.send(packet);
// 接收:
byte[] buffer = new byte[1024];
packet = new DatagramPacket(buffer, buffer.length);
ds.receive(packet);
String resp = new String(packet.getData(), packet.getOffset(), packet.getLength());
ds.disconnect();
// 关闭:
ds.close();
/**
* 16进制表示的字符串转换为字节数组
*
* @param hexString 16进制表示的字符串
* @return byte[] 字节数组
*/
public static byte[] hexStringToByteArray(String hexString) {
hexString = hexString.replaceAll(" ", "");
int len = hexString.length();
byte[] bytes = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
// 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节
bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
.digit(hexString.charAt(i + 1), 16));
}
return bytes;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 总结
以上就是本篇的全部内容, 主要介绍了 : 基于 UDP 协议的 Socket API , 以及利用这些 API 写了一个最简单客户端服务器网络通信程序。
上次更新: 2024/04/27, 22:21:35