Your assignment is to do the following, by modifying and extending the wclient outline file:
You can test your program by contacting the server, ulam.cs.luc.edu, and requesting files. If you contact on port 4715, you get a response from a new port (the standard behavior). This doesn't go through NAT firewalls, so if you contact ulam2 on port 4716 you get a response from the same port. No matter what file you ask for, the file you get is always the same. However, by asking port 4715 for the following names, you get the indicated behavior:
vanilla Normal transfer
At this point, the only ones that work on port 4716 are vanilla, lose2 (losedata2) and dup2 (dupdata2).
In order to get the basic vanilla transfer working, there are two things you need to do, as outlined above:
If you run the existing wclient.java (with wumppkt.java), and you have network access that doesn't block the necessary ports, your output should look something like this:
Looking
up address of ulam.cs.luc.edu... got it!
req size = 12, filename=vanilla
rec'd packet: len=520; proto=1; opcode=2; src=(10.0.0.1/60000); time=4
DATA packet blocknum =
1
An Assessment of the Programming Language Pascal
by Niklaus Wirth, developer of Pascal
1. What is reliable software?
Reliable is the attribute for a person, an organization, or a mechanism
that you can trust, that you can depend on, that is worthy of your
confidence. For example, a reliable clock is one that indicates
accurate time even during an earthquake, a reliable railway system is
one where trains run punctually even during a snowstorm, a reliable
bridge is a bridge that doesn't crack even under heahard timeout
hard timeout
hard timeout
hard timeout
hard timeout
...
What's going on here is that the server sent you Data[1], but your ACK didn't go to the right place, so it never sent you Data[2].
If you don't get Data[1], that is, you got nothing but error and status messages, try uncommenting the SAMEPORT line, because most likely a NAT router is blocking the Data[1] from a new port. If you do this, you will get both Data[1] and Data[2], because your ACK[1] now is going to the correct port (4715). But you won't get past Data[2], because you are not yet ever sending ACK[2]. You will probably get multiple Data[2] packets, because you will resend ACK[1] multiple times and each one will trigger a new Data[2].
The first step is to fix the ACK port, by appropriate placement of something like
latchport = replyDG.getPort();
ackDG.setPort(latchport);
(In general, you probably only want to set latchport once, on receipt of the first Data[1], but at this point it won't matter if you set it on every packet.) You can put this in with the other ackDG settings. At this point, in the SERVERPORT case you should now get Data[1] and Data[2]. Because your repeated ACK[1]'s are now going to the correct port, you should get multiple Data[2]'s, because each time you send ACK[1] the server will respond with Data[2]. This behavior is quite similar, overall, to that of the SAMEPORT setting without the above fix.
(If you're using the SAMEPORT case because you're at home and you have a NAT router, that's fine, but you should still make the above fix anyway, and then come in to Loyola to verify that the SERVERPORT case works properly. Having the SERVERPORT case work is a requirement.)
The second step is to increment expected_block, so that the arrival of Data[2] results in ACK[2] rather than ACK[1]. This is done with
expected_block++;
You can put this anywhere after the line
ack = wp.new ACK(wumppkt.BUMPPROTO, expected_block);
The line above creates an ack with the current expected_block, and you want to update expected_block for the next block. Alternatively, you can place a line
expected_block = data.blocknum();
before the ack creation, because this sets expected_block to the block number of the block that just arrived.
At this point you should get the entire file (11 blocks), with timeouts at the end because you are not properly handling the end-of-transmission case (last block has < 512 bytes of data). Because repeated ACK[11]'s don't trigger any new transmissions at the server side (why?), you won't get multiple copies of the last packet.
In general, you should verify that the arriving block number matches expected_block, as part of other sanity checks, before incrementing the latter. But you can worry about that later.
The next steps are to implement the sanity checks. The most important are to check the incoming port and also the packet's block number (to see that it matches expected_block), but you should also check the packet's IP address and size and opcode (watch the order!).