搜索吧:关键词:android, udp, 局域网, lan,广播,源代码
最近公司在做一个游戏项目,互联网对战方面的东东已经差不多搞定,还剩下局域网方面的东东没做,大概的功能需求是需要达到像飞鸽差不多的效果吧,但是在网络查了一天关于android的局域网广播的资料,不管是国内的还是国外的,发现没多少,大部分都是问,但是具体怎么解决的有答案的很少,自己摸索了一下,今天上午做了一个demo,能够看到局域网的通信效果了。有了个demo看到效果了就感觉有了很大的希望了。
关于广播组的ip问题,可以参看这篇帖子http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/net/MulticastSocket.html,不是什么自己ip地址后面改为255,也不是改成网关之类的。
下面把demo的客户端和服务器端代码贴出来:
package com.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import android.content.Context; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.Toast; public class MulticastServer implements Runnable{ private InetAddress mBroadcastAddr; private DatagramSocket mSocket; private DatagramPacket mDatagram; // private String mSendData = "AAAA"; private byte[] mBuffer = null; // mSendData.getBytes(); public static final int SERVER_SEND_PORT = 4445; public static final int CLIENT_RECEIVE_PORT = 4446; //Seehttp://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/net/MulticastSocket.html public static final String BROADCAST_IP = "234.5.6.7"; private Thread mThread = null; private static final String TAG = "MulticastServer"; private Context mContext = null;
public MulticastServer(Context context){ Log.d(TAG, "######## MulticastServer ##########"); mContext = context; WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); WifiManager.MulticastLock multicastLock = wifiManager.createMulticastLock("mydebuginfo"); multicastLock.acquire(); try { mSocket = new DatagramSocket(SERVER_SEND_PORT); } catch (SocketException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { mBroadcastAddr=InetAddress.getByName(BROADCAST_IP); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.d(TAG, "MulticastServer"); mBuffer = getLocalIpAddress().getBytes(); String str = new String(mBuffer); Log.d(TAG, "mBuffer = " + str); mDatagram = new DatagramPacket(mBuffer, mBuffer.length, mBroadcastAddr, CLIENT_RECEIVE_PORT); mThread = new Thread(this); } public void startSend() { Log.d(TAG, "startSend"); SEND_FLAG = true; mThread.start(); } public void stopSend() { SEND_FLAG = false; } private boolean SEND_FLAG = true; @Override public void run() { // TODO Auto-generated method stub while(SEND_FLAG) { broadcast_data(); } } private String sendStr = ""; private void broadcast_data() { try { Log.d(TAG, "broadcast_data"); mSocket.send(mDatagram); sendStr = new String(mDatagram.getData()); Log.d(TAG, "send ok data = " + sendStr); mHandler.sendEmptyMessage(TOAST_MSG_SEND); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface .getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf .getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { Log.e("WifiPreference IpAddress", ex.toString()); } return ""; } private final int TOAST_MSG_SEND = 0x01; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch(msg.what) { case TOAST_MSG_SEND: Toast.makeText(mContext, sendStr, Toast.LENGTH_SHORT).show(); } } }; }
下面是Client端代码:
package com.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.Toast; public class MulticastClient implements Runnable { private MulticastSocket mMultiSocket; private InetAddress mAddress; private boolean mScan = false; private Thread mThread = null; private byte[] mBuffer = new byte[256]; private DatagramPacket mDatagram = null; private static final String TAG = "MulticastClient"; private Context mContext = null; public MulticastClient(Context context) throws IOException { mContext = context; Log.d(TAG, "######## MulticastClient #########"); mAddress = InetAddress.getByName(MulticastServer.BROADCAST_IP); mMultiSocket = new MulticastSocket(MulticastServer.CLIENT_RECEIVE_PORT); mMultiSocket.joinGroup(mAddress); Log.d(TAG, "MulticastClient"); mThread = new Thread(this); // scan_recv(); } public void startReceive() { this.mScan = true; mThread.start(); } public void stopReceive() { this.mScan = false; } @Override public void run() { // TODO Auto-generated method stub Log.d(TAG, "run"); scan_recv(); } private String receiveStr = ""; public void scan_recv() { // DatagramPacket packet; while (mScan) { Log.d(TAG, "scan_recv"); try { mDatagram = new DatagramPacket(mBuffer, mBuffer.length); mMultiSocket.receive(mDatagram); receiveStr = new String(mDatagram.getData()); Log.v(TAG, "^^^^^^^^^data = " + receiveStr + "^^^^^^^^^^^^"); mHandler.sendEmptyMessage(TOAST_MSG_RECEIVE); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); this.mScan = false; } try { Log.d(TAG, "sleep"); Thread.sleep(100); // sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private final int TOAST_MSG_RECEIVE = 0x01; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case TOAST_MSG_RECEIVE: Toast.makeText(mContext, receiveStr, Toast.LENGTH_SHORT).show(); } } }; }
不过有个问题,在模拟器上收不到消息,只能收自己的,跟真机通信不了,试了网上别人说的还是没效果,反正有几个平板可以用,就不折腾这个问题了,用知道怎么解决这个问题的童鞋麻烦教我一下啦,谢谢。
截了一张demo图,这是模拟器上自己发送,自己接收的效果。
整个demo的代码我放到我的下载里面,想要的可以自己去取。(别给我留邮箱,留也没时间发)