程序员子龙(Java面试 + Java学习) 程序员子龙(Java面试 + Java学习)
首页
学习指南
工具
开源项目
技术书籍

程序员子龙

Java 开发从业者
首页
学习指南
工具
开源项目
技术书籍
  • 基础

  • JVM

  • Spring

  • 并发编程

  • Mybatis

  • 网络编程

    • Netty 入门
    • Netty中的Option和ChildOption参数解析
    • Netty ByteBuf介绍
    • Netty 心跳机制
    • Kryo 的序列化和序列化
    • Netty粘包拆包
    • Netty 编解码器
    • 网络编程IO模式
    • Netty TCP长连接集群方案
    • 序列化和反序列化
    • 使用 UDP 的 Socket API 实现服务端
      • 什么是 Socket(套接字)
      • TCP 协议和 UDP 协议的区别和特点
      • 基于 UDP 协议的 Socket API
        • 服务端
        • 客户端
      • 总结
    • Netty向客户端发送及接收16进制数据
    • Spring Boot与Netty的完美结合:打造高性能网络通信
  • 数据库

  • 缓存

  • 设计模式

  • 分布式

  • 高并发

  • SpringBoot

  • SpringCloudAlibaba

  • Nginx

  • 面试

  • 生产问题

  • 系统设计

  • 消息中间件

  • Java
  • 网络编程
程序员子龙
2024-04-27
目录

使用 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

需要注意的是: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

# 总结

以上就是本篇的全部内容, 主要介绍了 : 基于 UDP 协议的 Socket API , 以及利用这些 API 写了一个最简单客户端服务器网络通信程序。

上次更新: 2024/04/27, 22:21:35
序列化和反序列化
Netty向客户端发送及接收16进制数据

← 序列化和反序列化 Netty向客户端发送及接收16进制数据→

最近更新
01
一个注解,优雅的实现接口幂等性
11-17
02
MySQL事务(超详细!!!)
10-14
03
阿里二面:Kafka中如何保证消息的顺序性?这周被问到两次了
10-09
更多文章>
Theme by Vdoing | Copyright © 2024-2024

    辽ICP备2023001503号-2

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式