For learning purposes, I am implementing UDP with the mechanisms of TCP (so that it guarantees safe transfer).
The Semaphore
I am using is binary, so its sem = new Semaphore(1);
.
I use this semaphore to control the entrance for my sendBuf
, which is a List
containing all packages which have been send, but not yet confirmed. Since I sometimes remove packages out of it when I get an ACK, I need to make sure I am not iterating with one thread while another thread is deleting something out of it.
The thing which is really bugging me is this:
public void timeoutTask(long seqNum) {
System.out.println("Timeout for package with SeqNum " + seqNum
+ " happened.");
timeoutValue *= 2;
try {
System.out.println("Acquire? in timeouttask");
sem.acquire();
System.out.println("Acquired! in timeouttask");
} catch (InterruptedException e1) {
System.out.println("semaphore not acquired");
e1.printStackTrace();
}for (FCpacket packet : sendBuf) {
System.out.println("Iterating!");
if (packet.getSeqNum() == seqNum) {
System.out.println("Package for seqNum " + seqNum + " found!");
reSendData = packet.getSeqNumBytesAndData();
DatagramPacket reSendPacket = new DatagramPacket(reSendData,
reSendData.length, hostaddress, SERVER_PORT);
try {
clientSocket.send(reSendPacket);
System.out.println("Packet with seq " + seqNum
+ " send again");
packet.setTimestamp(0);
startTimer(packet);
new ReceiveHandler(reSendData, reSendData.length,
clientSocket, rcvData, UDP_PACKET_SIZE, this).run();
} catch (IOException e) {
System.out.println("Couldn't send package");
e.printStackTrace();
}
}
}
sem.release();
System.out.println("released! in timeouttask");
Console output gives me the following:
Acquire? in timeouttask
Acquired! in timeouttask
Iterating!
Paket for seqNum 1 found!
Packet with seq 1 send again
So it gets the semaphore, starts iterating, it even sends the package, so by now it should Either: Iterate again ("iterating!") OR release the semaphore. None of the above happens, it is just stuck. I have no idea why - any ideas?