android socket 广播,Android DatagramSocket实现数据广播

代码的基本思想是:创建两个线程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

Enumerationen = null;

try {

en = NetworkInterface.getNetworkInterfaces();

} catch (SocketException e2) {

// TODO Auto-generated catch block

e2.printStackTrace();

}

while (en.hasMoreElements()) {

NetworkInterface ni = en.nextElement();

Enumerationias = 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();

}

}

}

阅读(1605) | 评论(0) | 转发(0) |

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值