view src/fdl/FDLindaServ.java @ 92:ea4ee892baf5

commit
author kazz <kazz@cr.ie.u-ryukyu.ac.jp>
date Thu, 22 Apr 2010 16:13:03 +0900
parents 82a292aa41ad
children 96c63bc659d4
line wrap: on
line source


package fdl;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.spi.AbstractSelector;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.logging.Level;


public class FDLindaServ  {
	static final int MAX_REQ = 1;
	static final int FAIL = (-1);
	static final int DEF_PORT = 10000;
	public int port = DEF_PORT;
	AbstractSelector selector;
	private ServerSocketChannel ssChannel;
	public TupleSpace tupleSpace;
	public MetaEngine me;
	
	public static void main(final String[] args) {
		final String usages = "usage: FDLindaServ [-p port]";
		
		int port = DEF_PORT;
		//引数判定
		try {
			for (int i=0; i<args.length; ++i) {
				if("-p".equals(args[i])) {
					port = Integer.parseInt(args[++i]);					
				} 
			}
		} catch (NumberFormatException e) {
			System.err.println(usages);
			return;
		}
		try {
			FDLindaServ serv;
			serv = new FDLindaServ(port);
			serv.mainLoop();
		} catch (IOException e) {
			System.err.println("Server Communiation Problem.");
		}
	}
	
	public void mainLoop() {
		MetaLinda ml = new MetaLinda(tupleSpace, this);
		me = new NullMetaEngine(ml);
		//me = new MetaLogEngine(ml);
		me.mainLoop();
	}

	public FDLindaServ(int port) throws IOException {
		this.port = port;
		//セレクタを生成
		selector = SelectorProvider.provider().openSelector();		
		//ソケット・チャネルを生成・設定
		ssChannel = SelectorProvider.provider().openServerSocketChannel();
		ssChannel.socket().setReuseAddress(true);
		// this should work for IPv6/IPv4 dual stack
		// check this using netstat -an result tcp46.
		try {
			InetSocketAddress address = new InetSocketAddress("::", port);
			ssChannel.socket().bind(address);		
		} catch (SocketException e) {
			// for some bad IPv6 implementation
			ssChannel.socket().bind(new InetSocketAddress(port));
		}
		ssChannel.configureBlocking(false);
		this.log(Level.INFO,"Server: litening at "+ssChannel);
		//セレクタにチャンネルを登録
        tupleSpace = new TupleSpace(this);
		ssChannel.register(selector, SelectionKey.OP_ACCEPT, new AcceptHandler(this, ssChannel,tupleSpace));


	}

	public void checkTuple() {
		checkTuple(0);
	}
	
	public void checkTuple(long timeout) {
		// セレクタによる監視    
		try {
			if (selector.select(timeout)>0) {
//              this does not work because #it.remove() is not called.
//				for(SelectionKey s:selector.selectedKeys()) {
//					TupleHandler handler = (TupleHandler)s.attachment();
//					handler.handle(s);
//				}
			    for (Iterator<SelectionKey> it = selector.selectedKeys().iterator();it.hasNext(); ) {
			        SelectionKey s = it.next();
			        it.remove();
					TupleHandler handler = (TupleHandler)s.attachment();
					handler.handle(s);
				}
			}
		} catch (ClosedChannelException e) {
			// we have to do something...
		} catch (IOException e) {
		}
	}
	

	public void log(Level level,String msg) {
		System.err.println(msg);
		if (level==Level.SEVERE)
			new IOException().setStackTrace(null);
	}
}