/* JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine Release Version 2.4 A project from the Physics Dept, The University of Oxford Copyright (C) 2007-2010 The University of Oxford This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Details (including contact information) can be found at: jpc.sourceforge.net or the developer website sourceforge.net/projects/jpc/ Conceived and Developed by: Rhys Newman, Ian Preston, Chris Dennis End of licence header */ package org.jpc.j2se; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.logging.Level; import java.util.logging.Logger; /** Forwards packets between pairs of connections * * @author Ian Preston */ public class EthernetHubServer implements Runnable { private List<Client> clients = new ArrayList<Client>(); private ServerSocket sock; public EthernetHubServer(int port) { try { sock = new ServerSocket(port); } catch (IOException ex) { Logger.getLogger(EthernetHubServer.class.getName()).log(Level.SEVERE, null, ex); } new Thread(this).start(); System.out.println("Started EthernetHub Server on port " + port); } public void run() { //wait for connections Socket client; int count = 1; while (true) { try { client = sock.accept(); synchronized (clients) { Client c = new Client(client, count++); if (clients.size() % 2 == 1) { clients.get(clients.size()-1).setPartner(c); c.setPartner(clients.get(clients.size()-1)); } clients.add(c); new Thread(new Forwarder(c)).start(); } System.out.println("Accepted Connection from client " + (count -1)); } catch (IOException ex) { Logger.getLogger(EthernetHubServer.class.getName()).log(Level.SEVERE, null, ex); } } } public class Forwarder implements Runnable { DataInputStream in; DataOutputStream out; Client us; Client them = null; Forwarder(Client us) { this.us = us; in = us.getIn(); } public void run() { while (them == null) if (us.getPartner() != null) them = us.getPartner(); else try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(EthernetHubServer.class.getName()).log(Level.SEVERE, null, ex); } out = them.getOut(); try { while (true) { long start = System.currentTimeMillis(); long total = 0; for (int i = 0; i < 1000; i++) { int size = in.readInt(); total += size; byte[] packet = new byte[size]; in.readFully(packet); // System.out.println("Received a packet from client " + us.id); try { out.writeInt(packet.length); out.write(packet); out.flush(); // System.out.println("Forwarded a packet to client " + next.id); } catch (IOException e) { System.out.println("Client " + us.id + " couldn't contact partner."); } } long end = System.currentTimeMillis(); System.out.println("Bandwith " + (total*1000/(end-start)) + " bytes/second"); } } catch (IOException e) { Logger.getLogger(EthernetHubServer.class.getName()).log(Level.SEVERE, null, e); } } } public static void main(String[] args) { int port = Integer.parseInt(args[0]); new EthernetHubServer(port); } private class Client { DataOutputStream out; DataInputStream in; public int id; private Client partner; Client(Socket sock, int id) { this.id = id; try { sock.setTcpNoDelay(true); sock.setPerformancePreferences(0, 2, 1); out = new DataOutputStream(sock.getOutputStream()); in = new DataInputStream(sock.getInputStream()); } catch (IOException ex) { Logger.getLogger(EthernetHubServer.class.getName()).log(Level.SEVERE, null, ex); } } public void setPartner(Client partner) { this.partner = partner; } public Client getPartner() { return partner; } public DataOutputStream getOut() { return out; } public DataInputStream getIn() { return in; } } }