「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」
安卓接收UDP广播的例子
我们在互联网产品公司呆习惯了,给我们一个地址一个端口,我们就拿来直接连接就行了。在同一个局域网下,我们不知道对方的IP,是怎么连接对方的呢,像我们以前在网吧玩的单机局域网游戏,为什么一进入游戏,就可以联机玩了呢?IP地址是经常变动的,它为什么不需要我们手动输入IP了呢。带着这些疑问,接着看该文章。
UDP广播是什么
广播顾名思义,是指由一台主机向局域网的其它机器发送消息的过程。 因为是无连接的,并且一对多发送消息,所以概念中广播只能使用UDP的方式。
在主机端:通过某个端口不断的发送广播内容,内容包含IP地址和端口。
在客户端: 通过某个端口监听广播内容,解析广播内容,去除ip地址和端口,然后使用TCP连接。
在UDP广播中,又分为两种模式
- 定向广播,又叫直接广播,向某台在网络中的设备发送数据,这种广播会经过路由器到达指定的位置。
- 有限广播,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机,不会经过路由器
看看百科的解释
有限广播地址也称为本地广播地址,TCP/IP协议规定32位全为1的IP地址(255.255.255.255)用于本网广播。 在主机不知道本机所处的网络时(如主机的启动过程中),只能采用有限广播方式,通常由无盘工作站启动时使用,希望从网络IP地址服务器处获得一个IP地址。
广播地址包含一个有效的网络号和主机号,技术上就称为直接广播地址。
有限广播的数据包里不包含自己的ip地址,而直接广播地址里包含自身的ip地址。
发送广播
我用JAVA去实现发送广播的过程,创建数据包传输对象DatagramSocket 绑定端口.
public static void udpSend() {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(5000);
try {
// byte[] bytes = new byte[0]; //我不需要传递数据到服务器,所以写了个空的
byte[] bytes = "type_name".getBytes();
InetAddress inet = InetAddress.getByName("255.255.255.255");
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, inet, 1234);
DatagramSocket datagramSocket = new DatagramSocket();
datagramSocket.setSoTimeout(10000);
System.out.println("send");
datagramSocket.send(packet);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
接收广播
用循环阻塞接收发送过来的广播。
一般情况下,获取到主机地址后,再进行TCP连接。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
while (true)
udpReceiver();
}
}).start();
}
public static void udpReceiver() {
try {
DatagramSocket datagramSocket = new DatagramSocket(1234);
byte[] buff = new byte[1024];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
datagramSocket.receive(packet);
InetAddress ip = packet.getAddress();
String ipStr = ip + "";
String ip_new = ipStr.substring(1, ipStr.length());
System.out.println("ip_new:" + ip_new);
Log.d("====", "udpReceiver:" + ip_new);
// 获取内容: 约定好的词。 收到约定好的词之后,不再进行 while(true)
String text = new String(packet.getData(),0, packet.getLength());
Log.d("====", "text:" + text);
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}