bundle开发----Socket通讯(Server)

上一篇中实现了一个串口通讯的bundle,本例中我们来看看如何实现一个基于Socket的网络通讯bundle。

先来看看WifiBundle.java,代码如下:

package demo.wifi.bundle;

import java.io.IOException;  
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import org.osgi.framework.BundleContext;
import java.nio.channels.NotYetConnectedException;


public class WifiBundle {
	
	public static BundleContext bc = null;
	private final static Logger logger = Logger.getLogger(WifiBundle.class.getName());	
	public volatile static SocketChannel socketChannel = null;
	
	public static int port = 8081;
	public static ServerSocketChannel serverSocketChannel;
	
	public static boolean wifiRunningFlag = false;
    public static boolean wifiConnectionError = false;

	public static class WifiRunable implements  Runnable {	
		
		int totalSize = 0;
		int leftSize = 0;
		static String eventTopic = null;
		int arrayPosition = 0;
		boolean rtn;
		ByteBuffer receiveBuffer = ByteBuffer.allocateDirect(1024);
		
		public void run() {
	
			try {
				serverSocketChannel = ServerSocketChannel.open();
				serverSocketChannel.socket().setReuseAddress(true);
				if(!(serverSocketChannel.socket().isClosed()) && !(serverSocketChannel.socket().isBound())) {
					serverSocketChannel.socket().bind(new InetSocketAddress(port));
				}
				System.out.println("waiting for connection!");
				socketChannel = serverSocketChannel.accept();
				System.out.println("Wifi connection OK!");
			} catch (Exception ex) {
				ex.printStackTrace();
			}
	
			while(true) {
				//something wrong, waiting connection again
				if(wifiConnectionError == true) {
					try {
						System.out.println("waiting for re-connection request!");
						socketChannel = serverSocketChannel.accept();
						System.out.println("Wifi re-connection OK!");
						wifiConnectionError = false;
					} catch (Exception ex) {
						System.out.println("Wifi re-connection failed!");
						ex.printStackTrace();	
					}
				} else {
					try {
						//waiting for data
						while (wifiRunningFlag) {
							receiveBuffer.clear();
							rtn = receivePackage(receiveBuffer, 128);  
					        if(!rtn) {
					        	receiveBuffer.clear();
					        	break;
					        }
							receiveBuffer.clear();	
							sendPackage(receiveBuffer);						
						    receiveBuffer.clear();
						}
		
					} catch (Exception ex) {
						ex.printStackTrace();
						logger.log(Level.SEVERE, null, ex);
		
					}
				}
			}
		}
		
	}
	

	public static void sendPackage(ByteBuffer buffer) throws IOException {	
		try {
			socketChannel.write(buffer);
		} catch(IOException ex) {
		  ex.printStackTrace();
		  System.out.println("error occured in sendPackage()!");
		  wifiConnectionError = true;
		  return;
		}
		return;
	}
	

	public static boolean receivePackage(ByteBuffer byteBuffer, int size) throws IOException {
		
		int arrayPos = 0;
		int tempSize ;
		int leftSize = size;
		int totalSize = size;
		byte[] tempByteArray = new byte[totalSize];	
		ByteBuffer tempBuffer = ByteBuffer.allocateDirect(1);
		
		while((leftSize > 0) && (wifiRunningFlag == true))  {
			try {
				while(((tempSize = socketChannel.read(tempBuffer)) != -1)  && (wifiRunningFlag == true) ) {		
					tempBuffer.flip();
					if (tempSize == 0) {
						continue;
					} else {
						tempBuffer.get(tempByteArray, arrayPos, tempSize);
						leftSize --;
						arrayPos ++;
						if(leftSize == 0) {
							break;
						}
					}	
				}	
			  } catch (IOException ex) {
				ex.printStackTrace();
				System.out.println("error occured in receivePackage()!");
				wifiConnectionError = true;
				return false;
			}
			
		}
		
		byteBuffer.put(tempByteArray, 0, size);
		
		return true;	
	}
			
}	

再来看看Activator.java,代码比较简单,只需在start和stop函数中分别开始和终止socket收发进程。

package demo.wifi.bundle;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import demo.wifi.bundle.WifiBundle.WifiRunable;
import demo.wifi.bundle.WifiBundle;


public class Activator implements BundleActivator {
	

  public void start(BundleContext context) throws Exception {
	  
	  System.out.println("wifi bundle started!");  
	  WifiEventPublisher.bc = context;
	  WifiEventPublisher.eventRegister();

	  
	  //start Wifi new thread
	  new Thread(new WifiRunable()).start();
	  WifiBundle.wifiRunningFlag = true;
  }

  public void stop(BundleContext context) throws Exception {
	  WifiBundle.wifiRunningFlag = false;
	  WifiEventPublisher.EventUnregister();
	  if(WifiBundle.socketChannel.isConnected()) {
		  WifiBundle.socketChannel.close();
	  }
	  System.out.println("wifi bundle stoped!");
  }
}

bundle作为服务器端等待客户端的连接,连接建立之后将收到的数据回环发送给客户端。收发数据过程中若捕获到连接错误等异常,将通过设置出错标志位(WifiConnectionError)来实现自动重连功能。和串口通讯bundle一样,收到数据后,可以通过发布event的方式告知其他Bundle有数据到来,而该Socket Bundle只需负责纯粹的数据通讯,数据运算和其他处理交由其他Bundle负责,从而实现多Bundle协同动作。



你可能感兴趣的:(bundle开发----Socket通讯(Server))