Chinaunix首页 | 论坛 | 博客
  • 博客访问: 167690
  • 博文数量: 24
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 399
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-04 15:36
文章分类

全部博文(24)

文章存档

2017年(2)

2015年(5)

2014年(9)

2013年(8)

我的朋友

分类: Android平台

2014-08-16 14:34:28


代码的基本思想是:创建两个线程R/S, R刚开始会等待S的广播数据,如果R接收到S的广播数据,就回就一个字符串给S,S接收到字符串后打印出来
记得先在AndroidManifest.xml当中加入否则发送数据会报异常,出现EACCES错误.
直接看代码吧.


package com.helloworld;

import java.net.NetworkInterface;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Enumeration;

import org.apache.http.conn.util.InetAddressUtils;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.KeyEvent;
import android.view.InputEvent;
import android.widget.ListView;

public class MainActivity extends Activity {
    private static int UDP_PORT = 9111; // UDP通信端口
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // TODO Auto-generated method stub
        
        Receiver r = new Receiver(); // Receiver实例
        Sender s = new Sender(); // Sender实例
        
        r.start();  // 主线程根本不允许进行socket通信,所以Sender/Receiver都是基于线程的,这里启动他们就是了,先让r启动起来阻塞在receive函数上
        s.start(); // s启动后等待了3S才发数据
    }
    
    public static class Receiver extends Thread {
        public void run() {
            byte[] buf = new byte[1024];
            DatagramSocket sock = null;
            DatagramPacket pack = null;
            
            try {
                sock = new DatagramSocket(UDP_PORT);
            } catch (SocketException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            /*
            try {
                sock.setBroadcast(true); // 这一步可以省掉,因为默认是true
            } catch (SocketException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            */
            
            pack = new DatagramPacket(buf, buf.length);
            
            System.out.println("Receiver# Waiting...");
            
            try {
                sock.setSoTimeout(5000); // 接收等待时长
            } catch (SocketException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            try {
                sock.receive(pack);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
                
            System.out.println("Receiver# Got from " +
                    pack.getAddress().toString() + " : " +
                    pack.getPort() + " -> " +
                    new String(buf, 0, pack.getLength())); // 如果你确定收到的数据是字符串,需要打印的话这里要new一个String出来,用pack.getData().toString()打印出来是一堆16进制数
            
            // 等待500MS后再发数据出去
            try {
                Thread.sleep(500);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            String smsg = new String("I'm a server...");
            DatagramPacket spack = new DatagramPacket(smsg.getBytes(), smsg.getBytes().length, pack.getAddress(), pack.getPort());
            
            try {
                sock.send(spack);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println("Receiver# Sent to " + pack.getAddress().toString() + ":" + pack.getPort() + " -> " + smsg.toString());
            
            sock.close();
        }
    }
    
    public static class Sender extends Thread {
        public void run () {
            DatagramSocket sock = null;
            String s = new String("HHHHHHello");
            
            /* 打印所以网络设备上绑定的IP
            Enumeration en = null;
            try {
                en = NetworkInterface.getNetworkInterfaces();
            } catch (SocketException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            
            while (en.hasMoreElements()) {
                NetworkInterface ni = en.nextElement();
                
                Enumeration ias = ni.getInetAddresses();
                
                while (ias.hasMoreElements()) {
                    InetAddress ia = ias.nextElement();
                    
                    if (ia.isLoopbackAddress() ||
                        ia.isLinkLocalAddress() ||
                        InetAddressUtils.isIPv6Address(ia.getHostAddress())) {
                        continue;
                    }
                    if (!InetAddressUtils.isIPv4Address(ia.getHostAddress())) {
                        continue;
                    }
                    
                    System.out.println("IP: " + ia.getHostAddress().toString() + " for " + ni.toString());
                }
            }
            */
            
            // 等3S再发,防止另外一边还没有准备好接收
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            InetAddress ia = null;
            
            try {
                ia = InetAddress.getByName("255.255.255.255"); // 广播地址
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println("Sender# LocalHost: " + ia.getHostAddress().toString());
            System.out.println("Sender# IA " + ia.toString());
            
            try {
                sock = new DatagramSocket();
            } catch (SocketException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            /* 同样可以省掉
            try {
                sock.setBroadcast(true);
            } catch (SocketException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            */
            
            DatagramPacket spack = new DatagramPacket(s.getBytes(), s.getBytes().length, ia, UDP_PORT);
            
            try {
                sock.send(spack);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            System.out.println("Sender# Sent to 255.255.255.255:" + UDP_PORT + " -> " + s.toString());
            System.out.println("Sender# Then wait response...");
            
            byte[] rbuf = new byte[1024];
            DatagramPacket rpack = new DatagramPacket(rbuf, rbuf.length);
            
               // 设置一个超时时间,别让receive一直阻塞
            try {
                sock.setSoTimeout(3000);
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            boolean timeout = false;
            
            try {
                try {
                    sock.receive(rpack); // 这里的receive没有指定端口号,我想不通为什么他能接收到数据,在Receiver里面第一次接收时如果不指定端口号,就会出空指针异常,这里还需要再找找原因??????
                } catch (SocketTimeoutException e1) {
                    timeout = true;
                    e1.printStackTrace();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            if (timeout) { // 不知道怎么判断到底接收到数据没,我用rpack.getLength()取长度,总是会>0,所以这里用个标志
                System.out.println("Sender# Wait timeout...");
            } else {
                System.out.println("Sender# Got:" + new String(rbuf, 0, rpack.getLength()));
            }
            
            sock.close();
        }
    }
}
阅读(2588) | 评论(0) | 转发(0) |
0

上一篇:Qt webkit编译

下一篇:C++解析Json练习

给主人留下些什么吧!~~