A program that implements a simplified FTP client based on UDP; since UDP does not provide reliability, the program implements its own reliability mechanism based on the stop-and-wait protocol. See a GIF of me using it below!
- Supports sending a file to the server over UDP; before transmission, the client and server go through an initial handshake process
to exchange control information about the file transfer. The handshake takes place over TCP, while the actual file transfer is carried out
over UDP. See the following figure:
- The TCP
Socket
is used to exchange information about the file name to be sent, its length, the initial sequence number, as well as the UDP port number from the server. - The provided file is read chunk-by-chunk; each chunk becomes the payload of an
FtpSegment
for transmission to the server; theFtpSegment
itself is encapsulated in a UDPDatagramPacket
and then written to the UDP socket. - The sequence number for segments starts at the initial sequence number received from the server during the handshake process and is incremented per every
segment transmitted (not byte, unlike TCP). The "ACK" packets received from the server as
DatagramPacket
's carry the sequence number of the next expected segment at the server. The ACKDatagramPacket
's are de-encapsulated toFtpSegment
's in order to obtain the acknowledgment number. - As soon as a segment is transmitted, the client starts a retransmission timer (as is typical of a stop-and-wait protocol). If the correct ACK arrives, the timer is stopped. If the timer expires, the segment is retransmitted and the timer is restarted.
- The server terminates a file transfer session if it does not receive any UDP packets from the client during a certain amount of time; to prevent the client program from waiting indefinitely for an ACK, the client aborts the file transfer if it does not receive an ACK within a connection timeout period.
-i <file_name>
specifies the name of the file to be sent to the server; REQUIRED-s <server_name>
specifies the hostname of the server (ex. cslinux.ucalgary.ca); defaults tolocalhost
-p <port_number>
specifies the port number of the server; note that this is the port number at which the server is running. This is DIFFERENT from the port number used for the server's UDP socket. See the image below:
In the above image, you see a server process P1
open a DatagramSocket
with port number 6428
. Similarly, our server will open a DatagramSocket
at its own
chosen port number. The server's UDP Socket port number is DIFFERENT from the server's port number itself.
-t <timeout_interval>
specifies the time in milliseconds after which a segment is retransmitted if an ACK is not received; defaults to 1000 milliseconds (1 second).
-p <port_number>
specifies the port number of the server; the-p
flags should match when running both the client and server. Otherwise the client will be unable to connect. Defaults to2025
.-i <initial_seq_num>
specifies the initial sequence number to be used by the server. This is communicated to the client during the TCP handshake process. Defaults to1
.-d <average_delay>
specifies the average amount of time the server will wait before sending each ACK; specified in milli-seconds. Default is1
.-l <segment_loss_probability>
specifies the probability that the server will drop an arriving segment (to simulate packet loss which is typical in UDP-based transport). Default is0.010
(1%).-x <seq_number_to_be_dropped>
specifies the sequence number of the segment to be dropped by the server; this is useful when debugging as you can force the server to always drop a specific segment. Defaults to-1
(no segment is forcefully dropped).-t <idle_time>
specifies the time in milliseconds after which the server will shutdown if it does not receive aDatagramPacket
from the client. Default is5000
.-r <seed>
specifies the seed for the random number generator; use the same seed every time to produce the same drop and delay results. Defaults to13579
.
-
Start the server by running:
java -jar server/ftpserver.jar [-p <port_number>] [-i <initial_seq_num>] [-d <average_delay>] [-l <segment_loss_probability>] [-x <seq_number_to_be_dropped>] [-t <idle_time>] [-r <seed>]
- Start the client by opening up a new terminal and running:
cd client
javac *.java
java StopWaitDriver -i client_files/<name_of_file_to_transfer>
[-s <server_name>]
[-p <port_number>]
[-t <timeout_interval>]