咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

Android通过UDP广播实现发现服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class UDPSearch{

private final String TAG = this.getClass().getSimpleName();
private final Object mLock;
private DatagramSocket socket = null;
private UDPCallback callback;
private Thread threadReceive,threadSend;

public UDPSearch(UDPCallback callback) {
this.callback = callback;
this.mLock = new Object();
}


public void start(){

threadReceive = new Thread(new UDPReceive());
threadSend = new Thread(new UDPSend());

threadReceive.start();
threadSend.start();
}
public void stop(){

if(threadSend != null){
threadSend.interrupt();
threadSend = null;
}
if(threadReceive != null){
threadReceive.interrupt();
threadReceive = null;
}
}


class UDPSend implements Runnable{

private final String TAG = this.getClass().getSimpleName();
private final int BROADCAST_PORT = 6666;
private final String BROADCAST_HOST = "255.255.255.255";
private final byte[] broadcastData = new byte[]{ 0x01 ,0x02, 0x03 ,0x04 };

@Override
public void run() {

Log.i(TAG,"run start");

try {

TimeUnit.SECONDS.sleep(2);
InetAddress inetAddress = InetAddress.getByName(BROADCAST_HOST);
socket = new DatagramSocket();
socket.setBroadcast(true);

Log.d(TAG, "create udp socket target port:" + socket.getPort() + " and local port : " + socket.getLocalPort());
//socket已创建,通知线程接收数据
synchronized (mLock){
mLock.notify();
Log.i(TAG, "notify create socket ok");
}
while (!Thread.currentThread().isInterrupted()) {
Log.d(TAG,"send udp broadcast target port: " + BROADCAST_PORT);
try{
socket.send(new DatagramPacket(broadcastData, broadcastData.length,
inetAddress, BROADCAST_PORT));
}catch (IOException io){
// 这种错误不应该结束发送广播,系统网络关闭可以复现。
// java.io.IOException: sendto failed: ENETUNREACH (Network is unreachable)
// Caused by: android.system.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable)
io.printStackTrace();
}
TimeUnit.SECONDS.sleep(2);
}
} catch (InterruptedException | UnknownHostException | SocketException e) {
e.printStackTrace();
}finally {
Log.i(TAG,"socket close");
if(socket != null){
socket.close();
socket = null;
}
}
Log.i(TAG,"stop");
}
}


class UDPReceive implements Runnable{

private final String TAG = this.getClass().getSimpleName();

@Override
public void run() {

Log.i(TAG,"run start");
if(socket == null){
try {
Log.w(TAG,"socket not init, wait mLock.");
synchronized (mLock){
mLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i(TAG, "stop wait mLock");
while (socket != null && !Thread.currentThread().isInterrupted()) {
try {
final int len = 256;
DatagramPacket datagramPacket = new DatagramPacket(new byte[len], len);
Log.i(TAG, "receive data block");
socket.receive(datagramPacket);
Log.i(TAG, "receive data size = " + datagramPacket.getLength());
callback.onReceivePacket(datagramPacket.getData(), datagramPacket.getLength());
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i(TAG,"stop");
}
}


}

1
2
3
public interface UDPCallback {
void onReceivePacket(byte[] data, int len);
}