庖丁解牛之仿《闪传》实现文件传输(中)

1.> 转载请标明出处

本文出自[HCY的微博]

一、概述

在上篇庖丁解牛之仿《闪传》实现文件传输(上)通过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);
        }
    }

}

上述代码都在TcpUdpLibrary(https://github.com/Money888/TcpUdpLibrary)中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值