diff --git a/ws2012/P2P/uebungen/4/src/node/Node.java b/ws2012/P2P/uebungen/4/src/node/Node.java index 629da466..ddb5bcec 100644 --- a/ws2012/P2P/uebungen/4/src/node/Node.java +++ b/ws2012/P2P/uebungen/4/src/node/Node.java @@ -172,13 +172,23 @@ public class Node { return true; } + /** + * Shoot a new broadcast packet to the network. + * + * @param command + * the command of the broadcast packet (by now only * + * {@link node.MessageType#STATUS} + * @param data + * the (optional) data. Depends on the command + */ private void sendBroadcast(byte command, byte[] data) { // Random id? int packet_id = generator.nextInt(); - sendBroadcast(packet_id, command, data); + forwardBroadcast(packet_id, command, data, null); } - protected void sendBroadcast(int packet_id, byte command, byte[] data) { + protected void forwardBroadcast(int packet_id, byte command, byte[] data, + SocketAddress originalSender) { ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE); buffer.put(MessageType.BROADCAST); @@ -186,29 +196,43 @@ public class Node { buffer.put(command); buffer.put(data); + // Needed because the buffer gets cleared after first send, so we save + // the current buffer in a byte[] + int bytesWrittenToBuffer = buffer.position(); + byte[] packet = new byte[bytesWrittenToBuffer]; + System.arraycopy(buffer.array(), 0, packet, 0, bytesWrittenToBuffer); + buffer.flip(); - // Needed because the buffer gets cleared after first send - byte[] packet = buffer.array(); - for (SocketAddress n : neighbors) { - // TODO: by now, we also send the packet back to the node it was - // received from... - try { - channel.send(ByteBuffer.wrap(packet), n); - } catch (IOException e) { - e.printStackTrace(); + if (!n.equals(originalSender)) { + try { + channel.send(buffer, n); + buffer.clear(); + buffer.put(packet); + } catch (IOException e) { + e.printStackTrace(); + } } } } + /** + * Send my status (that is all my neighbors) to a given node. + * + * @param reveiver + * the node to receive my info + */ protected void sendStatus(InetSocketAddress reveiver) { ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE); buffer.put(MessageType.STATUS); + for (SocketAddress n : neighbors) { buffer.put(BufferUtil.addrToBytes((InetSocketAddress) n)); } + buffer.flip(); + try { channel.send(buffer, reveiver); } catch (IOException e) { @@ -229,6 +253,11 @@ public class Node { } + // TODO: something to delete nodes from the overall network + protected void setNeighborsOfNode(String node, List neighbors) { + network.put(node, neighbors); + } + protected boolean hasAck(int ack_id) { return acks.containsKey(ack_id); } @@ -262,6 +291,7 @@ public class Node { if (idToRemove != -1) { removed = neighbors.remove(idToRemove); } + return removed != null; } diff --git a/ws2012/P2P/uebungen/4/src/node/UDPHandler.java b/ws2012/P2P/uebungen/4/src/node/UDPHandler.java index b30e691b..cc307296 100644 --- a/ws2012/P2P/uebungen/4/src/node/UDPHandler.java +++ b/ws2012/P2P/uebungen/4/src/node/UDPHandler.java @@ -80,9 +80,11 @@ public class UDPHandler implements Runnable { case MessageType.STATUS: InetSocketAddress originalSender = readIPFromBuffer(); - // Broadcast to my neighbors - node.sendBroadcast(packet_id, command, - BufferUtil.addrToBytes(originalSender)); + // Broadcast to my neighbors (in case of a STATUS broadcast + // "originalSender" and "data" are the same, because the only + // data of a STATUS broadcast is the original sender + node.forwardBroadcast(packet_id, command, + BufferUtil.addrToBytes(originalSender), originalSender); LOGGER.log( Level.INFO, @@ -109,13 +111,16 @@ public class UDPHandler implements Runnable { } private void receiveStatus(SocketAddress receivedFrom) { - List neighbors = new ArrayList(); + LOGGER.info("Received status from " + receivedFrom.toString()); + List neighbors = new ArrayList(); while (buf.hasRemaining()) { - neighbors.add(readIPFromBuffer()); + String node = readIPFromBuffer().toString(); + neighbors.add(node); } // Keep track of all neighbors.. + node.setNeighborsOfNode(receivedFrom.toString(), neighbors); } private InetSocketAddress readIPFromBuffer() {