前言
事情是这个样子的,实验室的那个横向项目有一个需求:同一个 WIFI 下的设备之间可以实现实时的语音聊天。
于是这两天抽空闲时间捣鼓了一下局域网通信。现在基本实现语音通信了,是基于 UDP 广播实现的,但是不知道是 UDP 丢包过于严重还是 PCM 数据采集/播放的问题,导致接收端的声音噪声很大,这个后续再研究研究,看看究竟是个什么问题。
这篇主要记录一下基于 UDP 如何实现(Java语言)一个简易的聊天室,内容包括:UDP 广播、局域网通信、Java 实现广播的发送和接收、测试。
UDP 广播
直观地理解,广播是指同时向子网中的多台设备发送消息,并且所有子网中的设备都可以接收到发送方发来的消息。发送消息的目标地址是全 1 的,也就是说 255.255.255.255。关于 UDP,包括单播、组播、广播等网上有很多介绍文章,这里就不赘述了。
局域网通信
或者准确的说,局域网内通信,因为局域网通信还包括网间通信。网内通信的好处是,不需要介入外网、服务器,通过内网的交换机就可以实现设备之间的通信。这样好处就很明显啦:一个是安全,因为数据不会经过网关流向外网;二一个是效率,因为少了在外网传输的时间,直接通过交换机通信,效率会高很多。这在对实时性要求较高的场合来说尤为重要,例如实时语音。更多关于局域网通信的知识详见网络。
基于 Java 的 UDP 广播发送和接收
我们知道 UDP 是通过数据报传数据的,所以主要涉及到的类就是 DatagramPacket,即数据报包。
看代码:
public class UDPManager {
private String TAG = UDPManager.class.getName();
private int sendPort = 10010; // 监听端口
private int receivePort = 10009; // 发送端口
public static final int BUFFER_SIZE = 2048;
public DatagramSocket socket;
public void init() {
try {
//新建一个 DatagramSocket,绑定接收端口
socket = new DatagramSocket(receivePort);
//开启数据接收
openReceiver();
//发送广播消息
sendBroadcast("Hello World!");
} catch (Exception e) {
e.printStackTrace();
}
}
public void openReceiver() {
//在子线程中接收数据
new Thread(() -> {
byte[] buffer = new byte[BUFFER_SIZE];
DatagramPacket dp = new DatagramPacket(buffer, BUFFER_SIZE);
while(socket != null) {
try {
socket.receive(dp);
String ip = dp.getAddress().getHostAddress();
Log.e(TAG, "收到来自 " + ip + " 的消息:" + new String(buffer).trim());
Arrays.fill(buffer, (byte)0); // 清空上一次收到的数据
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 发送字符串数据
* */
public void sendBroadcast(String dataStr) throws IOException {
if (socket != null) {
byte[] buffer = dataStr.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), sendPort);
socket.send(packet);
}
}
}
其实非常简单,注释里写得很清楚。指定好发送端口和接收端口就行。
测试
用了下面的工具辅助测试。(有一说一这工具挺好用的)
先创建一个 UDP 测试实例,监听设置中,对 10010 端口进行监听(跟代码中的发送端口一致),连接设置那里,选择的是 UDP 广播,目标 IP 自然也是255.255.255.255,端口与代码中的接收端口一致。
测试结果:
上图中打马赛克那个是我电脑的 IP 地址,上面我的手机和我的电脑进行了如下简单而不失优雅的对话:
手机:hello how are you
电脑:I am fine, thank you, and you?
手机:oh I am fine too
电脑:Oh that is very nice!
测试成功!
本篇完~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)