Non-Blocking mode for UDP
Non-Blocking UDP 指令使用方法如下:
import java.io.IOException; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator; import android.content.Context; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.util.Log; public class NIOUDPProcess { private String mRemote_IP = ""; private String mRemote_Port = ""; private String mReceive_Message = ""; private int mSenderPort = -1; private Thread udpClientThread,udpReceiverThread,udpSenderThread; private int MAX_PACKET_SIZE = 1024; private boolean isRunning = false; private Context mContext; private DatagramChannel mSenderChannel,mReceiverChannel,mChannel; private DatagramSocket mSenderSocket; private SocketAddress mSenderAddress; public static interface NIOUDPStatusListener { void displayMessage(String message); } NIOUDPStatusListener mServerStatusListenerCallback; public NIOUDPProcess(Context context, NIOUDPStatusListener callback) { mContext = context; mServerStatusListenerCallback = callback; } /** * Start NIO receiver process thread. * @param The port for binding and how many lines you want to bind. * @return */ public void startNIOUDPReceiverProcess(final int bind_port ,final int number) { udpReceiverThread = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Selector mSelector = Selector.open(); int port = bind_port; for(int i = 0; i < number; i++) { mReceiverChannel = DatagramChannel.open( ); mReceiverChannel.configureBlocking(false); mReceiverChannel.socket().bind(new InetSocketAddress(port)); mReceiverChannel.register(mSelector, SelectionKey.OP_READ); port++; } isRunning = true; ByteBuffer mReceiveBuffer = ByteBuffer.allocate(MAX_PACKET_SIZE); while(isRunning) receiveProcess(mReceiveBuffer, mSelector); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Open socket error."); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Bind socket error."); } } }); udpReceiverThread.start(); } /** * Stop NIO receiver process thread. * @return */ public void stopNIOUDPReceiverProcess() { isRunning = false; udpReceiverThread = null; } /** * Start NIO sender process thread. * @param The port and the ip for connecting. * @return */ public void startNIOUDPSenderProcess(final String connect_ip, final int connect_port) { udpSenderThread = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { mSenderPort = connect_port; mSenderChannel = DatagramChannel.open( ); mSenderSocket = mSenderChannel.socket( ); mSenderAddress = new InetSocketAddress(connect_ip, connect_port); mSenderChannel.socket( ).connect(mSenderAddress); mSenderChannel.configureBlocking(false); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Open socket error."); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Bind socket error."); } } }); udpSenderThread.start(); } /** * The process of which channel is used to receiving. * @param The buffer is for receiving. The selector for selecting the udp socket channel * which is used to receiving. * @return */ private void receiveProcess(ByteBuffer mReceiveBuffer, Selector mSelector) { try { mSelector.select(); IteratormIterator = mSelector.selectedKeys().iterator(); while(mIterator.hasNext()) { SelectionKey mClientKey = mIterator.next(); if(mClientKey.isReadable()) { mChannel = (DatagramChannel) mClientKey.channel(); mReceiveBuffer.clear(); if (mChannel.receive(mReceiveBuffer) != null) { mReceiveBuffer.flip(); int mSize = mReceiveBuffer.limit(); byte[] mMessageBuffer = new byte[mSize]; mReceiveBuffer.get(mMessageBuffer); String message = new String(mMessageBuffer); decomposePacket(message); mServerStatusListenerCallback.displayMessage(mRemote_IP+ "("+mRemote_Port+")"+ ":"+mReceive_Message+ "\r\n"); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Receive process error."); } } /** * The process of which channel is used to sending. * @param The buffer is for sending. The selector for selecting the udp socket channel * which is used to sending. * @return */ public void sendProcess(final String message) { if(mSenderChannel == null || mSenderSocket == null) return; if(mSenderSocket.isClosed()) return; udpClientThread = new Thread(new Runnable() { @Override public void run() { try { ByteBuffer mSendBuffer = ByteBuffer.allocate(MAX_PACKET_SIZE); mSendBuffer.put(makePacket(getWiFiIP(),""+mSenderPort,message).getBytes()); mSendBuffer.flip(); mSenderChannel.send(mSendBuffer, mSenderAddress); mServerStatusListenerCallback.displayMessage("Me:"+message+"\r\n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.e("BK","Send process error."); } } }); udpClientThread.start(); } /** * Make the special format packet including ip ,port and message. * @param The ip address ,port ,message of sender. * @return The composed packet. */ public String makePacket(String ip, String port, String message) { String section = "\r\n\r\n"; String return_Str = "ip:" + ip + section+ "port:" + port + section+ "message:" + message + section; return return_Str; } /** * Get the Wi-Fi ip address by using the WifiManager. * @return The ip address of Wi-Fi. */ public String getWiFiIP() { WifiManager wm = (WifiManager) mContext.getSystemService( Context.WIFI_SERVICE); WifiInfo wifiInf = wm.getConnectionInfo(); long ip = wifiInf.getIpAddress(); if( ip != 0 ) return String.format( "%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff)); else return "0.0.0.0"; } /** * Decompose the packet for getting remote ip ,remote port and remote message. * @return */ public void decomposePacket(String receive_message) { String[] spilt_message = receive_message.split("\r\n\r\n"); mRemote_IP = spilt_message[0].substring(spilt_message[0].indexOf(":")+1, spilt_message[0].length()); mRemote_Port = spilt_message[1].substring(spilt_message[1].indexOf(":")+1, spilt_message[1].length()); mReceive_Message = spilt_message[2].substring(spilt_message[2].indexOf(":")+1, spilt_message[2].length()); } }
沒有留言 :
張貼留言