Commit f4559a45 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

initialized clean Simonstrator-PeerfactSim.KOM-repository to FINALLY get rid...

initialized clean Simonstrator-PeerfactSim.KOM-repository to FINALLY get rid of huge blob objects and ancient history that is not relevant to the simonstrator-branch of PeerfactSim.KOM
parents
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Set;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
* The Class RealNetworkRoutingTable.
*/
public class RealNetworkRoutingTable {
/** The logger. */
private static Logger log = SimLogger.getLogger(RealNetworkRoutingTable.class);
private static RealNetworkRoutingTable instance;
private HashMap<NetID, InetAddrAndPort> routingHashMap;
/**
* Instantiates a new real network routing table.
*/
private RealNetworkRoutingTable() {
routingHashMap = new HashMap<NetID, InetAddrAndPort>();
}
/**
* Gets the single instance of RealNetworkRoutingTable.
*
* @return single instance of RealNetworkRoutingTable
*/
public static RealNetworkRoutingTable getInstance() {
if (null == instance) {
instance = new RealNetworkRoutingTable();
}
return instance;
}
/**
* Adds the real inet addr and port.
*
* @param virtualID the virtual netID from Peerfact
* @param realID the real IPv4 Adress
* @param realPort the real port
*/
public void addRealInetAddrAndPort( NetID virtualID, InetAddress realID, short realPort) {
if( virtualID == null )
return;
log.debug("Adding new host to routing table: Virtual/" + virtualID + " is reachable at Real/" + realID + ":" + realPort);
routingHashMap.put(virtualID, new InetAddrAndPort(realID, realPort));
}
public void addRealInetAddrAndPort(NetID virtualID, InetAddress realID) {
addRealInetAddrAndPort(virtualID, realID, (short) 13000);
}
/**
* Gets the real inet addr and port for virtual ip.
*
* @param receiverId the receiver id
* @return the real inet addr and port for virtual ip
*/
public InetAddrAndPort getRealInetAddrAndPortForVirtualIP(NetID receiverId) {
return routingHashMap.get(receiverId);
}
/**
* Gets the boot strap info with all known NetIDs
*
* @return the boot strap info
*/
public Set<NetID> getBootStrapInfo() {
return this.routingHashMap.keySet();
}
/**
* The Class InetAddrAndPort.
*/
protected class InetAddrAndPort {
private InetAddress realID;
private short realPort;
/**
* Instantiates a new "inet addr and port" - Bundle
*
* @param realID the real id
* @param realPort the real port
*/
public InetAddrAndPort(InetAddress realID, short realPort) {
this.realID = realID;
this.realPort = realPort;
}
/**
* Gets the inet addr.
*
* @return the inet addr
*/
public InetAddress getInetAddr () {
return realID;
}
/**
* Gets the port.
*
* @return the port
*/
public short getPort() {
return realPort;
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.Socket;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.realNetworking.RealNetworkRoutingTable.InetAddrAndPort;
import de.tud.kom.p2psim.impl.network.realNetworking.messages.RealNetworkingMessage;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
public class RealNetworkingNetLayer extends AbstractNetLayer {
/** The logger. */
static Logger log = SimLogger.getLogger(RealNetworkingNetLayer.class);
private static RealNetworkingNetLayerManager netLayerManager = RealNetworkingNetLayerManager.getInstance();
public RealNetworkingNetLayer(SimHost host, NetID netID) {
super(host, netID, new BandwidthImpl(Double.POSITIVE_INFINITY,
Double.POSITIVE_INFINITY), null, null);
/* Go online as default behaviour. */
this.goOnline();
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.api.network.NetLayer#send(de.tud.kom.p2psim.api.common.Message, de.tud.kom.p2psim.api.network.NetID, de.tud.kom.p2psim.api.network.NetProtocol)
*/
@Override
public void send(Message transLayerMsg, NetID receiverId, NetProtocol protocol) {
assert( transLayerMsg instanceof AbstractTransMessage );
if( isOnline() ) {
assert (isSupported(((AbstractTransMessage) transLayerMsg).getProtocol()));
/* First: Get IP and PORT from Routing Table. */
final RealNetworkRoutingTable routingTable = RealNetworkRoutingTable.getInstance();
final InetAddrAndPort realDestination = routingTable.getRealInetAddrAndPortForVirtualIP(receiverId);
/* Destination known at all? */
if( realDestination == null ) {
log.warn("Destination " + receiverId + " not know to me ("
+ this.getLocalInetAddress() + "). Dropping packet.");
return;
}
final NetMessage netLayerMsg = new IPv4Message(transLayerMsg, receiverId, this.getNetID());
final RealNetworkingMessage realNetworkMessage = new RealNetworkingMessage(netLayerMsg);
final TransProtocol transLayerMsgProto = ((AbstractTransMessage) transLayerMsg).getProtocol();
log.debug("Trying to send packet from Virtual/" + this.getNetID() + " to Virtual/" + receiverId + " via Real/" + realDestination.getInetAddr() + " with " + transLayerMsgProto.toString());
if (transLayerMsgProto.equals(TransProtocol.UDP)) {
if (hasAnalyzer) {
netAnalyzerProxy.netMsgEvent(netLayerMsg, getHost(),
Reason.SEND);
}
this.netLayerManager.sendUDPPacket(receiverId, realDestination, realNetworkMessage);
// } else if (transLayerMsgProto.equals(TransProtocol.TCP)) {
// Simulator.getMonitor().netMsgEvent(netLayerMsg, getHost(), Reason.SEND);
// new Thread(this.new SenderThreadTCP(receiverId, realDestination, realNetworkMessage)).start();
}
} else {
log.warn("Host " + this.getLocalInetAddress() + " is offline.");
}
}
/*
* (non-Javadoc)
*
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOnline()
*/
@Override
public void goOnline() {
if( this.isOnline() ) {
return;
}
log.debug("Host " + this.getLocalInetAddress() + " going online");
netLayerManager.hostGoOnline(this);
super.goOnline();
}
/*
* (non-Javadoc)
*
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#goOffline()
*/
@Override
public void goOffline() {
log.debug("Host " + this.getLocalInetAddress() + " going offline");
netLayerManager.hostGoOffline(this);
super.goOffline();
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.impl.network.AbstractNetLayer#isSupported(de.tud.kom.p2psim.api.transport.TransProtocol)
*/
@Override
protected boolean isSupported(TransProtocol protocol) {
return (protocol.equals(TransProtocol.UDP) || protocol.equals(TransProtocol.TCP));
}
/**
* The Class SenderThreadTCP.
*/
private class SenderThreadTCP implements Runnable {
private NetMessage netLayerMsg;
private NetID receiverId;
private InetAddrAndPort realDestination;
/**
* Instantiates a new sender thread tcp.
*
* @param receiverId the receiver id
* @param realDestination the real destination
* @param netLayerMsg the net layer msg
*/
public SenderThreadTCP(NetID receiverId, InetAddrAndPort realDestination, NetMessage netLayerMsg) {
this.receiverId = receiverId;
this.realDestination = realDestination;
this.netLayerMsg = netLayerMsg;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
final Socket tcpConnection = new Socket( realDestination.getInetAddr(), realDestination.getPort() );
final OutputStream oStream = tcpConnection.getOutputStream();
final ObjectOutputStream ooStream = new ObjectOutputStream(oStream);
ooStream.writeObject(netLayerMsg);
ooStream.close();
oStream.close();
tcpConnection.close();
} catch( ConnectException e ) {
log.error("Remote host not answering, dropping packet. Was supposed to go to Virtual/" + receiverId + " on Real/" + realDestination.getInetAddr() + ": " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking;
import java.util.HashMap;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.impl.network.AbstractNetLayerFactory;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
public class RealNetworkingNetLayerFactory extends AbstractNetLayerFactory {
/** The logger. */
private static Logger log = SimLogger.getLogger(RealNetworkingNetLayerFactory.class);
/** The routing table. */
private RealNetworkRoutingTable routingTable;
/** The net layer manager. */
private static RealNetworkingNetLayerManager netLayerManager = RealNetworkingNetLayerManager.getInstance();
/** The hostID to netIP translation hashmap. */
public static HashMap<Long, NetID> HOST_ID_TO_NETIP_TRANSLATION = new HashMap<Long, NetID>();
/**
* Instantiates a new real networking net layer factory.
*/
public RealNetworkingNetLayerFactory() {
routingTable = RealNetworkRoutingTable.getInstance();
netLayerManager.goOnline();
Simulator.getScheduler().setSimulationSpeedLocked(true);
Simulator.getScheduler().setRealTime(true);
}
/* (non-Javadoc)
* @see de.tud.kom.p2psim.api.common.ComponentFactory#createComponent(de.tud.kom.p2psim.api.common.Host)
*/
@Override
public RealNetworkingNetLayer createComponent(Host phost) {
SimHost host = (SimHost) phost;
NetID id = HOST_ID_TO_NETIP_TRANSLATION.get(host.getHostId());
final RealNetworkingNetLayer newHost = new RealNetworkingNetLayer(host,
id);
log.debug("createComponent: Creating new node: " + host + " with Virtual/" + id);
if( routingTable.getRealInetAddrAndPortForVirtualIP(id) == null ) {
log.warn("Host not known to routing table. Not created.");
return null;
}
return newHost;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.api.simengine.SimulatorObserver;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.network.realNetworking.RealNetworkRoutingTable.InetAddrAndPort;
import de.tud.kom.p2psim.impl.network.realNetworking.messages.RealNetworkingMessage;
import de.tud.kom.p2psim.impl.network.realNetworking.socketListener.RealNetworkingTcpListener;
import de.tud.kom.p2psim.impl.network.realNetworking.socketListener.RealNetworkingUdpListener;
import de.tud.kom.p2psim.impl.simengine.Scheduler;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
public class RealNetworkingNetLayerManager implements EventHandler {
/** The logger. */
protected static Logger log = SimLogger.getLogger(RealNetworkingNetLayerManager.class);
public static final int GLOBAL_SOCKET_PORT_TCP = 13000;
public static final int GLOBAL_SOCKET_PORT_UDP = 13001;
private static RealNetworkingNetLayerManager instance;
private ServerSocket tcpSocket;
private DatagramSocket udpSocket;
private RealNetworkingTcpListener listenerThreadTCP;
private RealNetworkingUdpListener listenerThreadUDP;
private SenderThreadUDP senderThreadUDP;
private ConcurrentLinkedQueue<UDPTransmission> udpTransmissionQueue;
private HashMap<NetID, RealNetworkingNetLayer> hostsAlive;
private final static int EVENT_DUMMY = 1;
private final static int EVENT_RECEIVE = 2;
/**
* Instantiates a new real networking net layer manager.
*/
private RealNetworkingNetLayerManager() {
hostsAlive = new HashMap<NetID, RealNetworkingNetLayer>();
udpTransmissionQueue = new ConcurrentLinkedQueue<UDPTransmission>();
/* Go Offline once Simulation is done. */
Simulator.getInstance().addObserver(new SimulatorObserver() {
@Override
public void simulationFinished() {
RealNetworkingNetLayerManager.getInstance().goOffline();
}
});
/* Schedule starting message, so simulator doesn't run away imediately. */
Event.scheduleImmediately(this, null, EVENT_DUMMY);
}
/**
* Gets the single instance of RealNetworkingNetLayerManager.
*
* @return single instance of RealNetworkingNetLayerManager
*/
public static RealNetworkingNetLayerManager getInstance() {
if (null == instance) {
instance = new RealNetworkingNetLayerManager();
}
return instance;
}
/**
* Go online globally.
*/
void goOnline() {
/* Create and open up socket. */
try {
/* Start up TCP! */
log.debug("Starting TCP listener on port " + GLOBAL_SOCKET_PORT_TCP);
this.tcpSocket = new ServerSocket(GLOBAL_SOCKET_PORT_TCP);
assert this.tcpSocket.isBound();
listenerThreadTCP = new RealNetworkingTcpListener(this.tcpSocket, this);
new Thread(listenerThreadTCP).start();
/* Start up UDP! */
log.debug("Starting UDP listener on port " + GLOBAL_SOCKET_PORT_UDP);
this.udpSocket = new DatagramSocket(GLOBAL_SOCKET_PORT_UDP);
listenerThreadUDP = new RealNetworkingUdpListener(this.udpSocket, this);
new Thread(listenerThreadUDP).start();
senderThreadUDP = new SenderThreadUDP(this.udpTransmissionQueue, this.udpSocket);
new Thread(senderThreadUDP).start();
/*
* Block till both threads are alive.
*/
while( !( listenerThreadTCP.isAlive() && listenerThreadUDP.isAlive()) ) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// None.
}
}
} catch (BindException e) {
log.fatal("Socket already in use. Second simulator running in background?");
System.exit(-1);
} catch (IOException e) {
log.fatal("Socket already in use. Second simulator running in background?");
System.exit(-1);
}
}
/**
* Go offline.
*/
public void goOffline() {
if( listenerThreadTCP != null ) {
listenerThreadTCP.stop();
}
if( listenerThreadUDP != null ) {
listenerThreadUDP.stop();
}
if( senderThreadUDP != null ) {
senderThreadUDP.stop();
}
try {
if (tcpSocket != null) { this.tcpSocket.close(); }
if (udpSocket != null) { this.udpSocket.close(); }
} catch (IOException e) {
log.error("Could not close socket on TCP/UDP port " + GLOBAL_SOCKET_PORT_TCP + "/" + GLOBAL_SOCKET_PORT_UDP);
}
this.tcpSocket = null;
this.udpSocket = null;
}
/**
* Host go online.
*
* @param realNetworkingNetLayer the real networking net layer
*/
public void hostGoOnline(RealNetworkingNetLayer realNetworkingNetLayer) {
hostsAlive.put(realNetworkingNetLayer.getNetID(), realNetworkingNetLayer);
}
/**
* Host go offline.
*
* @param realNetworkingNetLayer the real networking net layer
*/
public void hostGoOffline(RealNetworkingNetLayer realNetworkingNetLayer) {
hostsAlive.remove(realNetworkingNetLayer.getNetID());
}
/**
* Gets the UDP socket.
*
* @return the UDP socket
*/
public DatagramSocket getUDPSocket() {
return udpSocket;
}
/**
* Receive thread safe.
* Has to be synchronized as TCP and UDP listener threads might call
* at the same time.
*
* @param netMsg the net msg
*/
synchronized public void receiveThreadSafe(IPv4Message netMsg) {
/* Call once to update currentTime, so logs are correct. */
if (Simulator.getScheduler().getRealTime()) {
/* Wake scheduler up in case it's sleeping. */
final Scheduler scheduler = Simulator.getScheduler();
synchronized (scheduler) {
/*
* FIXME: check, if this works thread-safe...
*/
// scheduler.wakeUpThreadSafeAndInsertEventImmediately(netMsg,
// this, SimulationEvent.Type.MESSAGE_RECEIVED);
Event.scheduleImmediately(this, netMsg, EVENT_RECEIVE);
}
} else {
assert false: "Scheduler not set to realtime. NOT SUPPORTED.";
}
}
@Override
public void eventOccurred(Object content, int type) {
if (type == EVENT_RECEIVE) {
final IPv4Message msg = (IPv4Message) content;
final NetID recipient = msg.getReceiver();
/* Boardcast: Deliver msg to all hosts. */
if (recipient.equals(IPv4NetID.LOCAL_BROADCAST)) {
for (RealNetworkingNetLayer receiver : hostsAlive.values()) {
if (!receiver.getNetID().equals(msg.getSender())) {
receiver.receive(msg);
}
}
/* Else: Unicast. */
} else {
final RealNetworkingNetLayer receivingNetLayer = hostsAlive
.get(recipient);
if (receivingNetLayer != null) {
/* if == null, host is probably offline. */
receivingNetLayer.receive(msg);
}
}
}
}
/**
* Send udp packet.
*
* @param receiverId the receiver id
* @param realDestination the real destination
* @param realNetworkMessage the net layer msg
*/
public void sendUDPPacket(NetID receiverId, InetAddrAndPort realDestination, RealNetworkingMessage realNetworkMessage) {
udpTransmissionQueue.add(new UDPTransmission(receiverId, realDestination, realNetworkMessage));
synchronized(senderThreadUDP) {
senderThreadUDP.notifyAll();
}
}
/**
* The Class UDPTransmission.
*/
private class UDPTransmission {
private RealNetworkingMessage realNetworkMessage;
NetID receiverId;
/** The real destination. */
InetAddrAndPort realDestination;
/**
* Instantiates a new UDP transmission data set.
*
* @param receiverId the receiver id
* @param realDestination the real destination
* @param netLayerMsg the net layer msg
*/
public UDPTransmission(NetID receiverId, InetAddrAndPort realDestination, RealNetworkingMessage realNetworkMessage) {
this.receiverId = receiverId;
this.realDestination = realDestination;
this.realNetworkMessage = realNetworkMessage;
}
/**
* Gets the real network message.
*
* @return the real network message
*/
public RealNetworkingMessage getRealNetworkMessage() {
return realNetworkMessage;
}
}
/**
* The Class SenderThreadUDP.
*/
private class SenderThreadUDP implements Runnable {
private ConcurrentLinkedQueue<UDPTransmission> udpTransmissionQueue;
private boolean running = true;
private DatagramSocket udpSocket;
public SenderThreadUDP(ConcurrentLinkedQueue<UDPTransmission> udpTransmissionQueue, DatagramSocket udpSocket) {
this.udpTransmissionQueue = udpTransmissionQueue;
this.udpSocket = udpSocket;
}
/**
* Stop.
*/
public void stop() {
running = false;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while( running ) {
while(this.udpTransmissionQueue.isEmpty()) {
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
// None. Thanks.
}
}
UDPTransmission nextUp = this.udpTransmissionQueue.poll();
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(nextUp.getRealNetworkMessage());
oos.flush();
final byte[] buf= baos.toByteArray();
if( buf.length > 64000 ) {
log.warn("UDP message too long(" + buf.length + " bytes), could not be sent to " + nextUp.receiverId + ". Dropping.");
return;
}
final DatagramPacket packet = new DatagramPacket(buf, buf.length, nextUp.realDestination.getInetAddr(), RealNetworkingNetLayerManager.GLOBAL_SOCKET_PORT_UDP);
this.udpSocket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.messages;
import java.io.IOException;
import java.io.ObjectInputStream;
import de.tud.kom.p2psim.api.transport.TransMessage;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.transport.UDPMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
public class RealNetworkingDeserializer {
/**
* Deserialize overall message.
*
* @param ois the ois
* @return the message
* @throws IOException
* @throws ClassNotFoundException
*/
public static Message deserialize(ObjectInputStream ois) throws IOException, ClassNotFoundException {
int transMsgType = ois.readByte();
final IPv4NetID sender = new IPv4NetID(ois.readLong());
final IPv4NetID receiver = new IPv4NetID(ois.readLong());
final TransMessage transMsg = deserializeTransMsg(ois, transMsgType);
return new IPv4Message(transMsg, receiver, sender);
}
/**
* Deserialize transport msg.
*
* @param ois the ois
* @param transMsgType the trans msg type
* @return the trans message
* @throws IOException Signals that an I/O exception has occurred.
* @throws ClassNotFoundException the class not found exception
*/
private static TransMessage deserializeTransMsg(ObjectInputStream ois, int transMsgType) throws IOException, ClassNotFoundException {
if( transMsgType == RealNetworkingSerializer.NETMSG_PROTOCOL_NUMBER_UDP ) {
short senderPort = ois.readShort();
short receiverPort = ois.readShort();
int commId = ois.readInt();
boolean isReply = ois.readBoolean();
Message msg = (Message) ois.readObject();
return new UDPMessage(msg, senderPort, receiverPort, commId, isReply);
} else if( transMsgType == RealNetworkingSerializer.NETMSG_PROTOCOL_NUMBER_TCP ) {
return null;
// Not yet.
}
throw new IOException("Cannot parse protocol field in packet.");
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.messages;
import java.io.Serializable;
public class RealNetworkingDummyIPv4Message implements Serializable {
public RealNetworkingDummyIPv4Message() {
// None. Thanks. Dummy. zzz
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.messages;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Message;
// TODO: Auto-generated Javadoc
/**
* The Class RealNetworkingMessage.
*/
public class RealNetworkingMessage implements Serializable {
/** The logger. */
final static Logger log = SimLogger.getLogger(RealNetworkingMessage.class);
/** The net msg. */
private Message netMsg = null;
/**
* Instantiates a new real networking message.
*/
public RealNetworkingMessage() {
}
/**
* Instantiates a new real networking message.
*
* @param netMsg the net msg
*/
public RealNetworkingMessage(Message netMsg) {
this.netMsg = netMsg;
}
/**
* Write object.
*
* @param oos the oos
* @throws IOException Signals that an I/O exception has occurred.
*/
private void writeObject(ObjectOutputStream oos) throws IOException {
log.debug(RealNetworkingMessage.class.getName() + ".writeObject");
RealNetworkingSerializer.serialize(oos, netMsg);
}
/**
* This method is private but it is called using reflection by java
* serialization mechanism. It overwrites the default object serialization.
*
* <br/><br/><b>IMPORTANT</b>
* The access modifier for this method MUST be set to <b>private</b> otherwise {@link java.io.StreamCorruptedException}
* will be thrown.
*
* @param ois the ois
* @throws IOException an exception that might occur during data reading
* @throws ClassNotFoundException this exception will be raised when a class is read that is
* not known to the current ClassLoader
*/
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
log.debug(RealNetworkingMessage.class.getName() + ".readObject");
this.netMsg = RealNetworkingDeserializer.deserialize(ois);
// transientString = (String) ois.readObject();
}
/**
* This method is called after the deserialization has been done.
* Here you can make some final touches and do custom stuff with your deserialized instance.
* The access modifier can be any one you like.
*
* @return a reference to <b>this</b> object
* @throws ObjectStreamException throw this exception if you figure that something is wrong with your object
*/
private /*or public od protected or default*/ Object readResolve() throws ObjectStreamException {
System.out.println(RealNetworkingMessage.class.getName() + ".readResolve");
System.out.println("Feel free to do custom stuff here.");
// string += " (object modified in 'readResolve' method)";
return this;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.messages;
import java.io.IOException;
import java.io.ObjectOutputStream;
import de.tud.kom.p2psim.api.transport.TransMessage;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.transport.TCPMessage;
import de.tud.kom.p2psim.impl.transport.UDPMessage;
import de.tudarmstadt.maki.simonstrator.api.Message;
public class RealNetworkingSerializer {
public static final int NETMSG_PROTOCOL_NUMBER_TCP = 6;
public static final int NETMSG_PROTOCOL_NUMBER_UDP = 17;
public static void serialize(ObjectOutputStream oos, Message msg) throws IOException {
/* Net Message */
final IPv4Message netMsg = (IPv4Message) msg;
if( netMsg.getPayload() instanceof UDPMessage ) {
oos.writeByte(NETMSG_PROTOCOL_NUMBER_UDP);
} else if( netMsg.getPayload() instanceof TCPMessage ) {
oos.writeByte(NETMSG_PROTOCOL_NUMBER_TCP);
} else {
throw new IOException("Unable to parse transport protocol.");
}
oos.writeLong(((IPv4NetID) netMsg.getSender()).getID());
oos.writeLong(((IPv4NetID) netMsg.getReceiver()).getID());
/* Transport Message */
final TransMessage transMsg = (TransMessage) netMsg.getPayload();
oos.writeShort(transMsg.getSenderPort());
oos.writeShort(transMsg.getReceiverPort());
oos.writeInt(transMsg.getCommId());
oos.writeBoolean(transMsg.isReply());
if( transMsg instanceof TCPMessage ) {
oos.writeLong(((TCPMessage)transMsg).getSequenzNumber());
}
/* User Message */
/* TODO: Add special cases here. */
oos.writeObject(transMsg.getPayload());
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.socketListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.realNetworking.RealNetworkingNetLayerManager;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
/**
* The listener interface for receiving tcp events.
* The class that is interested in processing a tcp
* event implements this interface, and the object created
* with that class is registered with a component using the
* component's <code>addTcpListener<code> method. When
* the tcp event occurs, that object's appropriate
* method is invoked.
*
* @see TcpEvent
*/
public class RealNetworkingTcpListener implements Runnable {
/** The logger. */
private static Logger log = SimLogger.getLogger(RealNetworkingTcpListener.class);
/** The socket to listen on. */
private ServerSocket socket;
/** The assosicated netLayer. */
private RealNetworkingNetLayerManager netLayerManager;
/** Is thread still supposed to be running. */
private boolean running = false;
/** Indicate weather thread is alive already. */
private boolean alive = false;
/**
* Instantiates a new real networking tcp listener.
*
* @param tcpSocket the tcp socket
* @param realNetworkingNetLayerManager the real networking net layer manager
*/
public RealNetworkingTcpListener(ServerSocket tcpSocket, RealNetworkingNetLayerManager realNetworkingNetLayerManager) {
this.socket = tcpSocket;
this.netLayerManager = realNetworkingNetLayerManager;
this.running = true;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
if( running ) {
log.debug("TcpListener thread running.");
this.alive = true;
}
while( running ) {
try {
Socket currentSocket = socket.accept();
/*
*
* Block HERE till data packet is received.
*
*
* */
/* *Yeay* Got a msg! */
log.debug("Got a connection from: " + currentSocket.getRemoteSocketAddress() + " to: " + currentSocket.getLocalAddress() + ":" + currentSocket.getLocalPort()) ;
Object inputObject = null;
try {
InputStream iStream = currentSocket.getInputStream();
ObjectInputStream oiStream = new ObjectInputStream(iStream);
inputObject = oiStream.readObject();
oiStream.close();
iStream.close();
currentSocket.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assert( inputObject != null );
assert( inputObject instanceof IPv4Message );
final IPv4Message netMsg = (IPv4Message) inputObject;
/* Deliver msg to simulator. */
netLayerManager.receiveThreadSafe(netMsg);
} catch (SocketException e) {
/* Nothing. Socket was closed, thread will end now. */
} catch (IOException e) {
log.warn("Socket IOException: " + e.getMessage());
} catch (AssertionError e) {
log.warn("Assertion: " + e.getMessage());
}
}
}
/**
* Stop.
*/
public void stop() {
log.debug("TcpListener thread stopping.");
running = false;
}
/**
* Checks if this thread is alive.
*
* @return true, if is alive
*/
public boolean isAlive() {
return alive;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.realNetworking.socketListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.realNetworking.RealNetworkingNetLayerManager;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
/**
* The listener interface for receiving udp events.
* The class that is interested in processing a udp
* event implements this interface, and the object created
* with that class is registered with a component using the
* component's <code>addUdpListener<code> method. When
* the udp event occurs, that object's appropriate
* method is invoked.
*
* @see UdpEvent
*/
public class RealNetworkingUdpListener implements Runnable {
/** The logger. */
private static Logger log = SimLogger.getLogger(RealNetworkingUdpListener.class);
/** The socket to listen on. */
private DatagramSocket socket;
/** The assosicated netLayer. */
private RealNetworkingNetLayerManager netLayerManager;
/** Is thread still supposed to be running. */
private boolean running = false;
/** Indicate weather thread is alive already. */
private boolean alive = false;
/**
* Instantiates a new UDP listener.
*
* @param udpSocket the udp socket
* @param realNetworkingNetLayerManager the real networking net layer
*/
public RealNetworkingUdpListener(DatagramSocket udpSocket, RealNetworkingNetLayerManager realNetworkingNetLayerManager) {
this.socket = udpSocket;
this.netLayerManager = realNetworkingNetLayerManager;
this.running = true;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
if( running ) {
log.debug("UdpListener thread running.");
this.alive = true;
}
while( running ) {
try {
byte[] buf = new byte[65507];
DatagramPacket p = new DatagramPacket(buf, buf.length);
socket.receive(p);
/*
*
* Block HERE till data packet is received.
*
*
* */
/* *Yeay* Got a msg! */
/* Unserialize. */
Object inputObject = null;
try {
ByteArrayInputStream baos = new ByteArrayInputStream(buf);
ObjectInputStream oiStream = new ObjectInputStream(baos);
inputObject = oiStream.readObject();
oiStream.close();
baos.close();
} catch (ClassNotFoundException e) {
// None.
}
assert( inputObject != null );
assert( inputObject instanceof IPv4Message );
IPv4Message inputMessage = (IPv4Message) inputObject;
/* Deliver msg to simulator. */
netLayerManager.receiveThreadSafe(inputMessage);
} catch (SocketException e) {
/* Nothing. Socket was closed, thread will end now. */
} catch (IOException e) {
log.warn("Socket IOException: " + e.getMessage());
} catch (AssertionError e) {
log.warn("Assertion: " + e.getMessage());
}
}
}
/**
* Stop.
*/
public void stop() {
log.debug("UdpListener thread stopping.");
running = false;
}
/**
* Checks if this thread is alive.
*
* @return true, if is alive
*/
public boolean isAlive() {
return alive ;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.routed;
import java.util.HashMap;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
* An instance of this class is always passed with each fragment of a
* partitioned message.
*
* @author Bjoern Richerzhagen
* @version 1.0, 23.03.2012
*/
public class FragmentReceivedInfo {
/**
* For the broadcast case
*/
private HashMap<NetID, FragmentReceivedMap> receiverMaps = new HashMap<NetID, FragmentReceivedInfo.FragmentReceivedMap>();
/**
* For the unicast case
*/
private FragmentReceivedMap unicastMap;
private boolean notifiedListener = false;
/**
* Received another Fragment. Is the message complete now? Use this for
* broadcasts.
*
* @param receiver
* @param fragmentNumber
* @param totalNumberOfFragments
* @return
*/
public boolean receivedFragment(NetID receiver, int fragmentNumber,
int totalNumberOfFragments) {
if (fragmentNumber == 1 && totalNumberOfFragments == 1) {
return true;
}
if (!receiverMaps.containsKey(receiver)) {
receiverMaps.put(receiver, new FragmentReceivedMap(
totalNumberOfFragments));
}
FragmentReceivedMap map = receiverMaps.get(receiver);
return map.isCompleteNow(fragmentNumber);
}
/**
* Received another fragment, is the message complete now? Use this for
* unicasts.
*
* @param fragmentNumber
* @param totalNumberOfFragments
* @return
*/
public boolean receivedFragment(int fragmentNumber,
int totalNumberOfFragments) {
if (unicastMap == null) {
unicastMap = new FragmentReceivedMap(totalNumberOfFragments);
}
return unicastMap.isCompleteNow(fragmentNumber);
}
public boolean isListenerNotified() {
return notifiedListener;
}
public void setListenerNotified() {
notifiedListener = true;
}
/**
* Returns true, if the given segment has been received already by the
* broadcast-receiver.
*
* @param receiver
* @param fragmentNumber
* @return
*/
public boolean isReceived(NetID receiver, int fragmentNumber) {
FragmentReceivedMap map = receiverMaps.get(receiver);
if (map == null) {
return false;
}
return map.isReceived(fragmentNumber);
}
/**
* Returns true, if the given segment has already been received by the
* unicast receiver.
*
* @param fragmentNumber
* @return
*/
public boolean isReceived(int fragmentNumber) {
if (unicastMap == null) {
return false;
}
return unicastMap.isReceived(fragmentNumber);
}
/**
* Returns true, if all fragments up (and including) the given number have
* been received.
*
* @param fragmentNumber
* @return
*/
public boolean isAllReceivedUpTo(int fragmentNumber) {
if (unicastMap == null) {
throw new AssertionError("This is not supposed to happen...");
}
return unicastMap.isAllReceivedUpTo(fragmentNumber);
}
/**
* Map for one receiver, as broadcasts could be partitioned as well.
*
* @author Bjoern Richerzhagen
* @version 1.0, 23.03.2012
*/
private class FragmentReceivedMap {
private boolean[] received;
private int numberOfFragements;
private int numberOfUniqueReceivedFragments = 0;
public FragmentReceivedMap(int numberOfFragments) {
this.received = new boolean[numberOfFragments];
this.numberOfFragements = numberOfFragments;
this.numberOfUniqueReceivedFragments = 0;
for (int i = 0; i < received.length; i++) {
received[i] = false;
}
}
/**
* This is called whenever a fragment arrives - it returns true, as soon
* as the message arrived completely
*
* @param receivedFragment
* @return
*/
public boolean isCompleteNow(int receivedFragment) {
if (!isReceived(receivedFragment)) {
received[receivedFragment - 1] = true;
this.numberOfUniqueReceivedFragments++;
}
return this.numberOfUniqueReceivedFragments == this.numberOfFragements;
}
/**
* Returns true, if all segments up to and including fragmentNumber have
* been received
*
* @param fragmentNumber
* @return
*/
public boolean isAllReceivedUpTo(int fragmentNumber) {
boolean complete = true;
int maxFragments = Math.min(fragmentNumber, received.length);
for (int i = 0; i < maxFragments; i++) {
complete = complete & received[i];
}
return complete;
}
/**
* True, if the given fragment (starting from 1) is already marked as
* received
*
* @param fragment
* @return
*/
public boolean isReceived(int fragment) {
return received[fragment - 1];
}
@Override
public String toString() {
String print = "";
for (int i = 0; i < received.length; i++) {
print += (received[i] ? 'X' : '#');
}
return print;
}
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment