/******************************************************************************* * Copyright (c) 2010 Freescale Semiconductor. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Serge Beauchamp (Freescale Semiconductor) - initial API and implementation *******************************************************************************/ package com.freescale.deadlockpreventer; import java.io.DataInputStream; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.util.HashMap; public class NetworkServer { ServerSocket server; public interface IService { void handle(Session session); void close(); } public static class Session { public Session(Socket socket) { this.socket = socket; try { input = new DataInputStream(socket.getInputStream()); output = new PrintStream(socket.getOutputStream()); key = NetworkUtil.readString(input); } catch (IOException e) { e.printStackTrace(); } } public Session(Socket socket, String key) throws IOException { this.socket = socket; this.key = key; String result = "ERROR"; input = new DataInputStream(socket.getInputStream()); output = new PrintStream(socket.getOutputStream()); NetworkUtil.writeString(output, key); result = NetworkUtil.readString(input); if (!result.equals("OK")) throw new IOException("Error connecting to network server: " + result); } public void close() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } public void ok() { try { NetworkUtil.writeString(output, "OK"); } catch (IOException e) { e.printStackTrace(); } } public void error() { try { NetworkUtil.writeString(output, "ERROR, NO SERVICE"); } catch (IOException e) { e.printStackTrace(); } close(); } public String getKey() { return key; } public DataInputStream getInput() { return input; } public PrintStream getOutput() { return output; } private String key; private Socket socket; private DataInputStream input; private PrintStream output; public boolean isClosed() { return socket.isClosed(); } } // the key is serviceID.sessionID HashMap<String, IService> services = new HashMap<String, IService>(); int actualPort = 0; int latestSessionID = 0; public static int DEFAULT_PORT = 43537; public String createNewSessionKey(String serviceID) { int sessionID = createNewSessionID(); return createKey(serviceID, sessionID); } private int createNewSessionID() { synchronized(this) { return ++latestSessionID; } } public int getListeningPort() { return server.getLocalPort(); } public NetworkServer() { } public void registerSevice(String sessionKey, IService service) { services.put(sessionKey, service); } private String createKey(String serviceID, int sessionID) { return serviceID + "." + Integer.toHexString(sessionID); } public Thread start(int port) { try { server = new ServerSocket(port); } catch (IOException e) { System.out.println(e); return null; } Thread thread = new Thread(new Runnable() { @Override public void run() { while (true) { try { final Socket socket = server.accept(); Session session = new Session(socket); IService service = services.get(session.getKey()); if (service != null) { session.ok(); service.handle(session); } else session.error(); } catch (SocketException e) { break; } catch (IOException e) { e.printStackTrace(); } } } }); thread.start(); return thread; } /** * Creates a new socket to the server from a client * @param value formatted address:port:session * @return * @throws IOException */ public static Session connect(String value) throws IOException { Socket socket; String serverAddress = value; String[] args = serverAddress.split(":"); int port = NetworkServer.DEFAULT_PORT; if (args.length > 1) port = Integer.parseInt(args[1]); try { socket = new Socket(args[0], port); } catch (UnknownHostException e) { throw new IOException(e.getMessage()); } String key = "0.0"; if (args.length > 2) key = args[2]; return new Session(socket, key); } public void stop() { for (IService service : services.values()) { service.close(); } services.clear(); try { server.close(); } catch (IOException e) { e.printStackTrace(); } server = null; } }