Broadcast/status should be working now

This commit is contained in:
senft-desktop 2012-11-30 10:24:10 +01:00
parent c4cd42d4c8
commit ed3e067b55
2 changed files with 51 additions and 16 deletions

View File

@ -172,13 +172,23 @@ public class Node {
return true;
}
/**
* Shoot a <b>new</b> 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<String> 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;
}

View File

@ -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<SocketAddress> neighbors = new ArrayList<SocketAddress>();
LOGGER.info("Received status from " + receivedFrom.toString());
List<String> neighbors = new ArrayList<String>();
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() {