1. 程式人生 > >庖丁解牛之仿《閃傳》實現檔案傳輸(中)

庖丁解牛之仿《閃傳》實現檔案傳輸(中)

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);
        }
    }

}