庖丁解牛之仿《閃傳》實現檔案傳輸(中)
阿新 • • 發佈:2019-01-29
1.> 轉載請標明出處
一、概述
在上篇庖丁解牛之仿《閃傳》實現檔案傳輸(上)通過WIFI API實現了兩臺手機所在網路的建立,那麼如何讓它們建立TCP連線呢?如何知道作為服務端一方的IP地址和埠號呢?方法是通過UDP多點廣播(多播)服務端的Ip地址和埠號,客戶端接收到這多播資訊之後,連線上服務端。
二、UDP多播訊息傳送者
ipv4中的多播地址範圍是:224.0.0.0到239.255.255.255
/**
* UDP廣播發送者
*/
class MulticastSender extends BaseThread {
private MulticastSocket multicastSocket;
private String multicastHost;
private int port;
public MulticastSender(String host, int port) throws IOException,
IllegalArgumentException {
if (TextUtils.isEmpty(host)) {
throw new IllegalArgumentException("host should not be null");
}
this.multicastHost = host;
this .port = port;
multicastSocket = new MulticastSocket();
// 新增多播地址
InetAddress groupAddr = InetAddress.getByName(host);
multicastSocket.joinGroup(groupAddr);
}
/**
* 傳送多播訊息內部實現
*
* @param message
* @throws IOException
*/
private void sendMessageInternal (byte[] message) throws IOException {
if (message == null) {
LogUtils.i("MulticastSender,message is null");
return;
}
DatagramPacket datagramPacket = new DatagramPacket(message,
message.length);
InetAddress groupAddr = InetAddress.getByName(multicastHost);
datagramPacket.setAddress(groupAddr);// 目標接收地址需要與多播地址相同
datagramPacket.setPort(port); // 目標埠號
multicastSocket.send(datagramPacket);
}
/**
* 傳送多播訊息
*
* @param message
*/
public void sendMessage(byte[] message) {
MulticastMessagePool.getInstance().addMessage(message);
}
@Override
public void run() {
while (!isExit) {
byte[] message = MulticastMessagePool.getInstance().getMessage();
if (message != null) {
try {
sendMessageInternal(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
multicastSocket.close();
}
}
如上程式碼實現了一個多播訊息傳送者,傳送者每次從訊息池中獲取到訊息後將其傳送出去,如果沒有訊息,則傳送執行緒等待訊息的到來。
三、UDP多播訊息接收者
class MulticastReceiver extends BaseThread {
private MulticastSocket multicastSocket;
private String host;
private int port;
private int recvBufSize = 1024;// 接收資料緩衝區大小
private OnUdpMulticastReceiveListener udpMulticastReceiveListener;
public MulticastReceiver(String host, int port, int recvBufSize)
throws IOException, IllegalArgumentException {
if (TextUtils.isEmpty(host)) {
throw new IllegalArgumentException("host should not be null");
}
this.host = host;
this.port = port;
this.recvBufSize = recvBufSize;
multicastSocket = new MulticastSocket(port);
InetAddress groupAddr = InetAddress.getByName(host);
multicastSocket.joinGroup(groupAddr);
}
@Override
public void run() {
try {
byte buf[] = new byte[recvBufSize];
DatagramPacket datagramPacket = null;
datagramPacket = new DatagramPacket(buf, buf.length,
InetAddress.getByName(host), port);
while (!isExit) {
multicastSocket.receive(datagramPacket);
int len = datagramPacket.getLength();
byte[] receivedData = new byte[len];
System.arraycopy(buf, 0, receivedData, 0, len);
onRecieveMessage(receivedData);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
multicastSocket.close();
}
}
/**
* 設定廣播接收監聽器
*
* @param l
*/
public void setOnUdpMulticastReceiveListener(OnUdpMulticastReceiveListener l) {
this.udpMulticastReceiveListener = l;
}
private void onRecieveMessage(byte[] message) {
if (udpMulticastReceiveListener != null) {
udpMulticastReceiveListener.onReceive(message);
}
}
}