protected void close() {
		try {
			Packet fin = Packet.getFinPacket(address);
			send(fin.pack());

			// wait until the router acknowledges our closing attempt
			while (!gotFIN) {
				if (socket.isClosed()) {
					// to prevent a race condition:
					if (!gotFIN) {
						throw new IOException("Socket closed before we got a FIN back!");
					}
				}
				Thread.yield();
			}

			// send back all the in-transit messages
			synchronized (packetsReceived) {
				for (Packet pkt : packetsReceived) {
					send(pkt.pack());
				}
			}
			for (Packet pkt : parent.inTransitMsgs) {
				send(pkt.pack());
			}

			// send a second fin to finalize the close
			send(fin.pack());
		} catch (IOException e) {
			System.err.println("Error while sending back packets.");
			//e.printStackTrace();
		}

		packetsReceived.clear();
		synchronized (parent) {
			parent = null;
		}
		finished = true;

		try {
			socket.close();
		} catch (IOException e) {
			System.err.println("Error while closing socket!");
			//e.printStackTrace();
		}
	}