CPSC 441 Assignments 1 to 5 solutions

$125.00

Original Work ?

Download Details:

  • Name: As-roltdt.zip
  • Type: zip
  • Size: 1.60 MB

Category: You will Instantly receive a download link upon Payment||Click Original Work Button for Custom work

Description

5/5 - (1 vote)

Assignment 1 CPSC 441

1 Objective
This assignment aims to achieve several objectives at the same time. The first objective is to learn
the basic structure of a client-server application. The second objective is to learn the general form
and requirements of programming assignments in this course. The third objective is to help you
refresh your Java programming skills and setup your development environment for the rest of
this course. Thus, while simple and straightforward, the expectation is that every student will
try and complete this assignment.
2 Specification
2.1 Overview
In this assignment, you will implement a program called GzipClient. You have to write code
to establish a TCP connection with a remote server, read the content of a given file from the local
file system, send it to the server for GZIP compression, receive the compressed file content and
save it to a new file in the local file system. While the server used in this assignment provides
GZIP compression, the client implementation is in fact independent of that and can be used to
obtain other services (e.g., encryption) by changing the server implementation.
2.2 Protocol
The protocol that the client and server use to communicate in this assignment is a custom protocol (i.e., designed by the instructor). The high-level behavior of the sender side and client side
of the protocol is presented in Programs 1 and 2, respectively:
Program 1 GzipServer
1: while not shutdown do
2: Listen for connection requests
3: Accept a new connection request from a client
4: while not end of input stream do
5: Read data from the socket input stream
6: Write compressed data to the socket output stream
7: end while
8: Close the output stream
9: Close the client socket
10: end while
2
Assignment 1 CPSC 441
Program 2 GzipClient
Input Parameters: server, inFile, outFile
1: Establish a TCP connection with server
2: Open the file specified by inFile for reading
3: Create the output file with name outFile
4: Read the input file and write to the socket
5: Read from the socket and write to the output file
6: Clean up (e.g., close the streams and socket)
2.3 Implementation
Let us start by discussing the server implementation, as the client implementation should comply with the server implementation. The following code snippet shows the actual implementation of the read and write operations in the server.
Socket socket = serverSocket.accept();
InputStream input = socket.getInputStream();
GZIPOutputStream output = new GZIPOutputStream(socket.getOutputStream(), true);
int readBytes = 0;
byte[] buff = new byte[MAX_BUFF_SIZE];
// while not EOF from client side
while ( (readBytes = input.read(buff)) != -1) {
output.write(buff, 0, readBytes);
output.flush(); // not needed, but a good practice
}
output.close(); // NEEDED to finalize compression
socket.close(); // non persistent server
The important thing to notice is that the server does not know how much data it has to read
from the client. In this implementation, the server keeps reading from its socket input stream
by repeatedly calling the read() method until it returns -1 (indicating the end of file was
reached or the connection was closed). Thus, at the client side, you have to signal to the server
that the transmission is complete by closing the socket output stream at the client side. This
will cause subsequent calls to read() method to eventually return -1. Unfortunately, the way
Java sockets are implemented, closing the input or output stream of a socket closes the socket
as well. To keep the socket open, e.g., to be able to read the compressed data coming from the
server, while closing its output stream, the client side program should use shutdownOutput()
method when it has transmitted the entire file.
3
Assignment 1 CPSC 441
The client implementation should have a similar structure. Specifically, as in the server, all read
and write operations should operate over a chunk of data (i.e., using a buffer). The size of the
buffer is a design decision but a multiple of TCP packet size is recommended for performance
reasons (e.g., 32 KByte). While a program can use the version of read and write methods that
operate over a single byte, its performance will suffer due to the overhead of single byte input
and output operations. An important aspect of your design is how to implement Steps 4 and 5
(see Program 2) to avoid deadlock, i.e., a situation where the client and server are blocked by each
other. To this end, you must consider implementing sending and receiving operations of the
client in separate threads that run independently from each other. Refer to the assignment notes
and tutorials for more detail on this.
2.4 Design Requirements
Your client design should be based on the following principles:
β€’ Block IO: Read and write operations must use a buffer to perform file and socket IO. As
discussed earlier, this is to avoid poor performance.
β€’ Parallel IO: Read and write operations on the socket must be implemented in separate
threads, namely one thread to read from the socket and one tread to write to the socket.
As discussed earlier, this is to avoid deadlock without any performance penalty.
3 Software Interfaces
3.1 Method Signatures
The required method signatures for class GzipClient are provided to you in the source file
GzipClient.java. There are two methods that you need to implement, namely the constructor GzipClient() and method gzip(). A brief description of gzip() is provided below. For
more information, refer to the Javadoc documentation provided in the source file.
β€’ void gzip(String inFile, String outFile)
This is the main method that reads the local file and communicates with the remote server
to create a GZIP compressed version of the file. The parameter inFile specifies the name
of the input file, while the parameter outFile specifies the name of the compressed file
to be created.
3.2 Exception Handling
Your implementation should include exception handling code to deal with all checked exceptions in your program. Print exception messages (i.e., the stack trace) to the standard system
output.
4
Assignment 1 CPSC 441
3.3 Running Your Code
A driver class named GzipDriver is provided on D2L to demonstrate how we are going to run
your code. Read the inline documentation in the source file GzipDriver.java for detailed information on how to use the driver class. Moreover, you can download the server program that
implements the server side of the protocol from D2L. The server program is provided in a jar file
named gzipserver.jar. The server comes with a README file, which includes instructions
on how to run it.
3.4 Console Output
Add print statements (using System.out.println) in your code to print the following information on the console:
1. When reading from the socket: println(β€œR ” + numBytes)
2. When writing to the socket: println(β€œW ” + numBytes)
where numBytes denotes the number of bytes read from or written to the socket. Do not directly print anything else to the console beyond exception messages and the above read/write
statements. For debugging purposes, you can use the global logger object defined in the
GzipDriver class, whose level can be set using the command line option -v. Refer to the
source file GzipDriver.java for more information. The logger can be used to write messages
to console during code development.
3.5 Design Document
Prepare and submit a design document to describe how you implemented Steps 4 and 5 in
Program 2. Follow the design document formatting requirements described on D2L.
Restrictions
β€’ You are not allowed to modify the method signatures provided to you. However, you can
(and should) implement additional methods and classes as needed in your implementation.
β€’ You have to write your own code for communicating with the server. Ask the instructor if
you are in doubt about any specific Java classes that you want to use in your program.
5

Assignment 2 CPSC 441

1 Objective The objective of this assignment is to practice network programming and learn about application layer protocols. Specifically, you will implement an HTTP client program to download a web object specified by its URL. 2 Specification 2.1 Overview In this assignment, you will implement an HTTP client called HttpClient from scratch. You have to write code to establish a TCP connection to a given server and send and receive HTTP messages. Your program should be able to download both binary and text objects. All downloaded objects are stored locally in the same directory where your program is running. 2.2 Implementation A high-level description of the internal operation of HttpClient is presented in Program 1. Program 1 HttpClient Input Parameter: url 1: Parse the input url to extract server address and object path 2: Establish a TCP connection with the server 3: Send a GET request for the specified object 4: Read the server response status and header lines 5: if response status is OK then 6: Create the local file with the object name 7: while not end of input stream do 8: Read from the socket and write to the local file 9: end while 10: end if 11: Clean up (e.g., close the streams and socket) The client program HttpClient should operate in non-persistent HTTP mode. This means that once the object is downloaded, the client closes the underlying TCP connection. The program takes as input the URL of the object to be downloaded. The input URL is a properly formatted URL with the following syntax: https://hostname[:port]/[pathname] where, β€’ [:port] is an optional part which specifies the server port. If no port is specified, use the default port 80 2 Assignment 2 CPSC 441 β€’ [pathname] is an optional part which specifies the object path on the server. If no pathname is specified, use the default name index.html 2.3 Sending GET Request To send an HTTP GET request, you should establish a TCP connection to the server on the specified port number. Then create a request using the pathname and send the request to the server. For writing ASCII formatted data to a socket, e.g., HTTP headers, you can create a string object and then call String.getBytes(“US-ASCII”) to convert the string to a sequence of bytes that can be written to the socket. Make sure to flush the output stream so that the data is actually written to the socket. Once the request is submitted, start reading the HTTP response from the socket. The local file name of the downloaded object should match the file name specified by the URL. For example, if the input URL is https://ict746x.cs.ucalgary.ca/files/medium.pdf then the object should be saved in file medium.pdf in the working directory of the client program. 2.4 Constructing GET Request To be compliant with what most web servers expect from a well-behaving web client, include the following header lines in your GET request: β€’ Host: – the host name of the server β€’ Connection: close For the protocol version, you can specify HTTP/1.1. 2.5 Reading Server Response You can use method InputStream.read() on the socket input stream to read an array of bytes that can be converted to a String object for parsing. Remember that each line of the response header is terminated with character sequence “\r\n”. Once you have read the entire header, you know the length of the body of the response, and subsequently can use method InputStream.read(byte[]) to read the body of the response. 3 Software Interfaces 3.1 Method Signatures The required method signatures for class HttpClient are provided to you in the source file HttpClient.java. There is only one method that you need to implement, namely method 3 Assignment 2 CPSC 441 get(). Refer to the Javadoc documentation provided in the source file for more information on this method. 3.2 Exception Handling Your implementation should include exception handling code to deal with all checked exceptions in your program. Print exception messages (the stack trace) to the standard system output. 3.3 Running Your Code A driver class named HttpDriver is provided on D2L to demonstrate how we are going to run your code. Read the inline documentation in the source file HttpDriver.java for detailed information on how to use the driver class. There are also a number of test URLs in the driver class that can be used to test the functionality of your program with a web server on ict746x.cs.ucalgary.ca, although you should be able to use any HTTP web server (e.g., python -m http.server) for testing purposes. 3.4 Console Output Add print statements (using System.out.println) in your code to print the following information on the console: 1. HTTP request (request line and header lines) 2. HTTP response (status line and header lines only) Do not directly print anything else to the console beyond exception messages and the above information. For debugging purposes, you can use the global logger object defined in the driver class, whose level can be set using the command line option -v. Refer to the driver class source file for more information. The logger can be used to write messages to console during code development. 3.5 Design Document Prepare and submit a design document (one page) to describe how you read and parse the server response. Explain what stream you used and how you read header lines and the object body. Follow the design document formatting requirements described on D2L. Restrictions β€’ You are not allowed to modify the method signatures provided to you. However, you can implement additional methods and classes as needed in your implementation. β€’ You are not allowed to use package java.net.http, and URL, URI, URLConnection classes or their subclasses for this assignment. Ask the instructor if you are in doubt about any specific Java classes that you want to use in your program. 4

Assignment 3 CPSC 441

1 Objective
The objective of this assignment is to practice server side network programming with TCP.
Specifically, you will implement a multi-threaded web server from scratch to serve web objects
to HTTP clients over the Internet.
2 Specification
2.1 Overview
In this assignment, you will implement a simple web server program called WebServer. Your
server is required to handle GET requests only. It has to check if the requested object is available,
and if so return a copy of the object to the client. The server should operate in non-persistent
HTTP mode. This means that once an HTTP request is served, the server closes the underlying
TCP connection. To inform the client that the connection is closed, include the connection close
header line in the server response:
Connection: close
2.2 Implementation
To handle multiple connections, the server has to be multi-threaded. In the main thread, the
server listens on a fixed port using a ServerSocket object. When it receives a TCP connection
request, the server accepts the request and processes it in a separate Worker Thread. That is, once
the server accepts a connection, it will spawn a new thread to parse the incoming HTTP request
and send an appropriate response to the client.
β€’ To prevent non-responsive clients from hogging server resources, if the worker thread
does not receive a request from the client within a given time period, the worker thread
must send an error message (with status code 408) to the client and close the connection.
β€’ The working directory of the web server is its root directory. That is, if the requested
object path is /object-path then the file containing the object is located on relative path
object-path in the working directory of the web server.
Programs 1 and 2 provide a high-level description of the web server’s main and worker thread
functionality.
3 Server Response
An HTTP response consists of a status line followed by a number of optional header lines. In the
case that the response includes an object, the content of the object is separated from the header
lines by an empty line.
2
Assignment 3 CPSC 441
Program 1 Main Thread
1: while not shutdown do
2: Listen for connection requests from clients
3: Accept a new connection request
4: Spawn a worker thread to handle the new connection
5: end while
6: Wait for worker threads to finish
7: Close the server socket and clean up
Program 2 Worker Thread
1: Set a timer to receive the client request
2: Read and parse the request
3: if request timeout then
4: Send Request Timeout error response
5: else if format error then
6: Send Bad Request error response
7: else if non-existence object then
8: Send Not Found error response
9: else
10: Send Ok response
11: Send the object content
12: end if
13: Close the socket and clean up
3.1 Status Line
The status line consists of three components, which are separated by one or more spaces:
HTTP/1.1 status-code status-phrase
As this is a simplified web server, your program needs to return responses with the following
status codes and phrases only:
β€’ 200 OK
Request is valid and the requested object is transmitted after the header lines.
β€’ 400 Bad Request
There was a problem with the format of the request. An HTTP request consists of a request line and several optional header lines. In this assignment, we assume that header
3
Assignment 3 CPSC 441
lines (if any header lines are present in the request) are properly formatted and only the request line may have formatting issues. A properly formatted request line consists of three
mandatory parts which are separated by one or more spaces, as follows:
GET /object-path HTTP/1.1
The command GET and protocol HTTP/1.1 are fixed, while the object-path is optional. If no object-path is provided, i.e., the request only specifies β€˜/’, then assume
index.html by default.
β€’ 404 Not Found
The requested object was not found on the server, i.e., the corresponding file does not exists
in the working directory of the web server.
β€’ 408 Request Timeout
The web server did not receive the client request within a pre-specified time period. This
time period is passed to the server as an input parameter.
3.2 Header Lines
To be compliant with what most web browsers expect from a well-behaving web server, your
web server must include several header lines in its response. Each header line is formatted as
follows:
field-name: field-value
where there is one (or more) space between β€˜:’ and filed-value.
β€’ If the response code is 200, include the following header lines:
Date – current date on the server
Server – name of your web server (your choice!)
Last-Modified – get it from the file system
Content-Length – length of the object
Content-Type – type of the object
Connection: close
β€’ For any other response code, include the following header lines only:
Date – current date on the server
4
Assignment 3 CPSC 441
Server – name of your web server (your choice!)
Connection: close
To format the date header field, you can use class SimpleDateFormat with format pattern
β€œEEE, dd MMM yyyy hh:mm:ss zzz”. Also, for the type of the object being transmitted,
whatever type is returned by method Files.probeContentType() is acceptable for this assignment.
4 Web Server Shutdown
4.1 Shutdown Method
Your server program is required to implement a shutdown method. When the shutdown is
called, the server should exit listening on the socket, clean up and terminate gracefully. To
implement shutdown, you can either use interrupt()/interrupted() methods of class
Thread or define a flag variable in your WebServer class and set it when the server is asked
to shutdown. Either way, since ServerSocket.accept() is a blocking call, the server never
checks the loop condition (see Program 1) while it is waiting for a client connection request.
Thus, you need to force the server thread to periodically time out to return from the blocking
method accept(), and check the shutdown status. This can be accomplished by setting the
socket timeout option using method ServerSocket.setSoTimeout().
4.2 Thread Management
Once the server is signalled to shut down, it has to wait a reasonable amount of time for the
currently running worker threads to terminate before it terminates. You can either write your
own code for thread management, e.g., keep track of active threads in a list and then wait (some
amount of time) for all of them to terminate, or use the executor service ThreadPoolExecutor
for executing and terminating threads. Refer to Java documentation for details and examples.
5 Software Interfaces
5.1 Method Signatures
The required method signatures for class WebServer are provided to you in the source file
WebServer.java. There are three methods that you need to implement, namely a constructor
and methods run and shutdown. Refer to the Javadoc documentation provided in the source
file for more information on these methods.
5.2 Exception Handling
Your implementation should include exception handling code to deal with all checked exceptions in your program. This includes catching the exceptions and printing exception messages
5
Assignment 3 CPSC 441
(or the stack trace) to the standard system output. Note that SocketTimeoutException is
part of the expected behavior of your code (due to setting socket timeout options) and should
not result in the web server termination.
β€’ Exceptions in the server’s main thread: If the server can recover from the exception (i.e.,
the exception only affected a worker thread) then continue with the normal execution of
the web server. Otherwise, terminate the server in an orderly way (i.e., clean up and close
all streams and sockets) as if it was shutdown by the user.
β€’ Exceptions in worker threads: Clean up, close all streams and sockets and terminate (i.e.,
return from the run method) the worker thread.
5.3 Running Your Code
A driver class named ServerDriver is provided on D2L to demonstrate how we are going
to run your code. Read the inline documentation in the source file ServerDriver.java for
detailed information on how to use the driver class.
5.4 Testing the Server
You should be able to use Telnet/putty, your Assignment 2 implementation, or even a web
browser to test your web server implementation. Yet another handy alternative is to use wget
or curl utilities to send GET requests to your server. To connect to your server, you need to
specify the server port number in the URL, as described in Assignment 1. You can give your
server a port number between 1024 and 65535. Keep in mind that some web browsers default
to HTTPS, so you need to change the settings of your browser to use HTTP for your web server,
otherwise you will get a connection error.
5.5 Console Output
Add print statements (using System.out.println) in your code to print the following information on the console:
1. Client information (IP address and port number) every time the server accepts a client connection.
2. HTTP request (request line and header lines) every time the server receives a request.
3. HTTP response (status line and header lines only) every time the server sends a response.
Do not directly print anything else to the console beyond exception messages and the above
information. For debugging purposes, you can use the global logger object defined in the
driver class, whose level can be set using the command line option -v. Refer to the driver class
source file for more information. The logger can be used to write messages to console during
code development.
6
Assignment 3 CPSC 441
5.6 Design Document
Prepare and submit a design document to explain what happens in your program if the method
shutdown() is called while some worker threads are still executing. Describe the sequence
of events that happens in your implementation once method shutdown is called. Follow the
design document formatting requirements on D2L.
Restrictions
β€’ You are not allowed to modify the class and method signatures provided to you. However,
you can (and should) implement additional methods and classes as needed in your implementation. Any changes in ServerDriver class will be overwritten during marking.
β€’ You are not allowed to use classes URL, URI, URLConnection or their subclasses for this
assignment. Ask the instructor if you are in doubt about any specific Java classes that you
want to use in your program. In general, as long as you are writing your own code to
implement HTTP protocol over TCP sockets, you should be fine.
7

Assignment 4 CPSC 441

1 Objective The objective of this assignment is to practice UDP socket programming and reliable data transfer. Specifically, you will implement a UDP-based program for reliable file transfer based on the Stop-and-Wait protocol. 2 Specification 2.1 Overview In this assignment, you will implement a simplified FTP client based on UDP called StopWaitFtp. Since UDP does not provide any data reliability, you will implement your own reliability mechanism based on the stop and wait protocol. The simplified client only supports sending a file to the server. Before the actual data 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. 2.2 Handshake The handshake takes place over a TCP connection and initiated by the client. The host name and port number of the server are provided to your program. Upon start, your program should open a TCP socket (with the provided server name and port number) as well as a UDP socket (using the no-argument constructor DatagramSocket()). Use the TCP socket to exchange information about the file name to be sent, its length, the initial sequence number and UDP port numbers on the client and server. All control messages during the handshake are in binary format. You can use the Java binary stream classes DataInputStream and DataOutputStream to read from and write to the TCP socket in binary format. Specifically, follow the message sequence presented in Program 1 (in the exact same order) to complete the handshake process: Program 1 Handshake Message Sequence 1. Send the local UDP port number used for file transfer as an int value 2. Send the name of the file as a UTF encoded string 3. Send the length (in bytes) of the file as a long value 4. Receive the server UDP port number used for file transfer as an int value 5. Receive the initial sequence number used by the server as an int value Do not forget to flush() the output stream to force TCP to send your data to the server at the end of the send section of the handshake. 2 Assignment 4 CPSC 441 3 Implementation 3.1 High Level Structure A high-level description of the internal operation of StopWaitFtp is presented in Program 2. Program 2 StopWaitFtp Open a TCP connection to the server Open a UDP socket Complete the handshake over TCP while not end of file do Read from the file and create a segment Send the segment and start the timer Wait for ACK, when correct ACK arrives stop the timer end while Close sockets and clean up 3.2 Sending File Content A file name is given to your program as input. Your program should read the file chunk-bychunk and then encapsulate each chunk in a segment for transmission to the server. The class FtpSegment is provided to you on D2L. Refer to the Javadoc documentation provided in the source file for more information on how to use this class. Specifically, class FtpSegment provides methods for creating segments with a given sequence number and payload, creating a UDP packet that encapsulates a segment, and creating a segment from a UDP packet, as demonstrated in method FtpSegment.main(). The maximum size of a segment payload is given by the constant FtpSegment.MAX_PAYLOAD_SIZE. 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. Once a segment is transmitted, you should wait to received an ACK for that segment. Your program should listen for arriving ACK segments from the server using the same UDP socket that is used for sending data segments to the server. The ACK segments received from the server carry the sequence number of the next expected segment at the server. That is, if the server receives a segment with sequence number n, then it sends an ACK segment with sequence number n + 1, indicating to the client to send segment n + 1 next. The ACK segments are regular segment objects that have no payload. 3 Assignment 4 CPSC 441 3.3 Retransmission Timer As soon as a segment is transmitted, the client should start a retransmission timer. The duration of the timeout interval is given to the client program as an input parameter. Class Timer can be used to schedule a recurring timer using method Timer.scheduleAtFixedRate(). To use the Timer class, you need to define a timer task class as well. A timer task is similar to a Thread class. The only difference is that it extends class TimerTask. In your program, you should create one Timer object when the program starts. Then use the timer object to start and stop recurring timer tasks. If an ACK arrives for the latest transmitted segment, you should cancel the recurring timer task by calling method TimerTask.cancel(). Note that calling the cancel method does not cancel a timer task that is currently executing. While this may result in an unnecessary retransmission of the segment that has been just ACKed, it is an acceptable behavior in this assignment. You may find it convenient to define two helper methods to start and stop the timer task. When the entire file transmission is complete, make sure to shutdown the timer instance itself. This is achieved by calling Timer.cancel() and Timer.purge() methods to cancel the timer object and any timer tasks attached to it. 3.4 Handling Concurrency Since the timer task runs concurrently with the main program, you should be careful when accessing any shared data. In particular, the last transmitted segment may be accessed concurrently by the main program and the timer task (for retransmission), which could lead to memory inconsistencies, e.g., retransmitting a segment by the timer task before it has been fully initialized by the main program. In general, such race conditions can be avoided by protecting access to the shared data using Java synchronized blocks. In StopWaitFtp, since the shared data is only one segment, a simple solution is to store a copy of the segment (to be transmitted when a timeout happens) in the timer task object itself when creating a timer task for the segment. 3.5 Design Requirements Your client design should be based on the following principles: β€’ Segment Payload: Create segments with the maximum payload size for good performance. Only the last segment from the client to the server may not carry sufficient data to by of maximum size. β€’ Retransmission Timer: Using socket timeout option to handle retransmissions is not allowed, as it could lead to incorrect behavior with duplicate ACKs. Your implementation must use the Timer class, as described above. Using a ScheduledExecutorService to implement retransmissions is also acceptable. 4 Assignment 4 CPSC 441 4 Software Interfaces 4.1 Method Signatures The required method signatures for class StopWaitFtp are provided to you in the source file StopWaitFtp.java. There are two methods that you need to implement, namely a constructor and method send. Refer to the Javadoc documentation provided in the source file for more information on these methods. 4.2 FtpSegment Class This class defines the structure of the segments exchanged between the sender (i.e., client) and receiver (i.e., server). Read the Javadoc documentation of the class for how to use it. Note that both data packets and ACKs are of type FtpSegment. Segments that go from the sender to receiver carry data, while segments that come from the receiver are ACKs that do not carry any data. 4.3 Exception Handling Your implementation should include exception handling code to deal with all checked exceptions in your program. This includes catching the exceptions and printing exception messages (or the stack trace) to the standard system output. After that, clean up, close all streams and sockets and return from the send method. 4.4 Testing Your Code A driver class named StopWaitDriver is provided on D2L to demonstrate how we are going to run your code. Read the inline documentation in the source file StopWaitDriver.java for detailed information on how to use the driver class. Moreover, you can download the server program that implements the service side of the protocol from D2L. The server program is provided in a jar file named ftpserver.jar. The server comes with a README which includes instructions on how to run it. Although you can check the transferred file in the working directory of the server for correctness, you should also correlate the output of your program with that of the server to verify correct protocol implementation. For example, you can correlate packet drops at the server with timeouts at the client, which should match. 4.5 Console Output Add print statements (using System.out.println) in your code to print the following information on the console: 1. send – every time the client sends a segment to the server. 2. ack – every time the client receives an ACK. 5 Assignment 4 CPSC 441 3. retx – every time a segment is re-transmitted due to timeout. 4. timeout – every time a timeout happens at the client. In the above, refers to the sequence number of the relevant data or ACK segment. Do not directly print anything else to the console beyond exception messages and the above information. For debugging purposes, you can use the global logger object defined in the driver class, whose level can be set using the command line option -v. Refer to the driver class source file for more information. The logger can be used to write messages to console during code development. 4.6 Design Document Prepare and submit a design document to describe the following aspects of your program: β€’ How did you implement retransmissions? Explain how you setup the timer and when you start and stop the transmission timer. β€’ What happens in your implementation if a timeout occurs at the same time that an ACK arrives from the server. Is there going to be a race condition in your program in that case? Explain your answer. Restrictions β€’ You are not allowed to modify the class and method signatures provided to you. However, you can (and should) implement additional methods and classes as needed in your implementation. Any changes in StopWaitDriver and FtpSegment classes will be overwritten during marking. β€’ You have to write your own code for sending and receiving UDP packets. Ask the instructor if you are in doubt about any specific Java classes that you want to use in your program. 6

Assignment 5 CPSC 441

1 Objective The objective of this assignment is to practice UDP socket programming and reliable data transfer. Specifically, you will implement a pipelined UDP-based program for reliable file transfer based on the Go-Back-N protocol, which is more efficient that the Stop and Wait protocol in Assignment 4. 2 Specification In this assignment, you will implement a simplified FTP client based on UDP called GoBackFtp. While this assignment is implemented independent of Assignment 4, it uses the same TCP/UDP design, handshake process and segment structure. Specifically, the description in this assignment is focused on the process of sending the file using Go-Back-N protocol. This requires implementing processes for sending segments and receiving acknowledgments to run concurrently, which is somewhat similar to the design of GzipClient in Assignment 1. Recall that, before the actual data 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. The handshake process is exactly the same as in StopWaitFtp program of Assignment 4, and thus is not repeated here. 3 Implementation 3.1 High Level Structure A high-level design of GoBackFtp is presented in Program 1. Program 1 GoBackFtp 1: Handshake with server 2: Create the re-transmission timer 3: Start the ACK receiving thread 4: Start the segment sending thread 5: Wait for the segment sending thread to finish 6: Wait for the ACK receiving thread to finish 7: Shutdown the re-transmission timer In addition to the handshake process, there are three main operations in GoBackFtp: 1. Creating and sending data segments, 2. Receiving and processing ACKs, 3. Re-transmission timeouts. 2 Assignment 5 CPSC 441 A critical aspect of GoBackFtp design is that these three operations should be executed concurrently. They are asynchronous operations that should not be serialized. It means that, while the program is sending segments, it should be able to receive ACKs and handle timeouts simultaneously. As such, your design should rely on two separate threads for sending segments and receiving ACKs, similar to Assignment 1, which run in parallel with a timer task that is in charge of timeouts. More details are provided on each of these design components in the following subsections. 3.2 Sending Thread The high-level design of the sending thread is described in Program 2. In GoBackFtp, the sender can have multiple in-flight segments. Once a segment is transmitted, it should be added to a Transmission Queue until the segment is acknowledged by the server. In other words, the transmission queue contains all those segments that have been transmitted but not acknowledged yet. The capacity of the transmission queue is determined by the window size of the Go-Back-N protocol, which is given to your program as an input parameter. The transmission queue is full if the number of segments in the queue is equal to the window size. Program 2 Sending Thread 1: while not end of file do 2: Read from the file and create a segment 3: Wait while transmission queue is full 4: Send the segment and add it to the transmission queue 5: Start timer if the segment is the first in the transmission queue 6: end while 3.3 Receiving Thread Your program should be listening for arriving ACK segments from the server using the same UDP socket that is used for sending data segments to the server. Recall that in Go-Back-N, ACKs are cumulative, meaning that an ACK with sequence number n indicates that all segments with sequence numbers smaller than n are received by the server, and the next expected segment is the segment with sequence number n. If an ACK with sequence number n is received, then check the transmission queue and remove all segments with sequence numbers smaller than n, as they have been received by the server. The high-level design of the sending thread is described in Program 3. Notice that if the transmission queue is empty, it does not necessarily mean that the file transfer is complete. Only when the queue is empty and the sending thread has finished, the receiving thread can finish. Also, as in Assignment 3, to give the receiving thread a chance to check the conditions of the while loop, you have to set the socket timeout options for the UDP socket using method 3 Assignment 5 CPSC 441 Program 3 Receiving Thread 1: while sending thread not finished or transmission queue not empty do 2: Receive ACK 3: if ACK is valid then 4: Stop re-transmission timer 5: Update the transmission queue based on the received ACK 6: Start re-transmission timer if the transmission queue is not empty 7: end if 8: end while DatagramSocket.setSoTimeout(). A received ACK is valid if it acknowledges any pending segments, i.e., its sequence number is greater than the sequence number of the first segment in the transmission queue. 3.4 Timeout Task Go-Back-N uses a single retransmission timeout which is set for the oldest unacknowledged segment in the window. In your program, a recurring timeout should be set for the first segment in the transmission queue (i.e., the segment at the head of the queue). If the timer goes off then all pending segments in the transmission queue are retransmitted to the server, as described in Program 4. Program 4 Timeout Task 1: for all segments in transmission queue do 2: Send the segment via the UDP socket 3: end for Note that, as explained in Assignment 4, the timeout task is scheduled to happen at regular intervals. This was achieved by using the method scheduleAtFixedRate() of class Timer. Thus, when a timeout occurs, there is no need to manually reschedule the next timeout task. Whenever the first segment in the queue is ACKed, then the receiving thread cancels the timeout that was set for that segment. 3.5 Handling Concurrency 3.5.1 Transmission Queue The transmission queue is a shared resource among the three concurrent process in GoBackFtp. Thus, access to the queue has to be synchronized to avoid race conditions. While this can be achieved using synchronized blocks in Java, the ConcurrentLinkedQueue class already provides this functionality using a highly efficient implementation. This queue has internal 4 Assignment 5 CPSC 441 locking mechanisms to prevent memory inconsistencies while allowing simultaneous access to the queue elements. It implements the generic Queue interface with all the familiar operations of a FIFO queue. It is recommended that you implement the transmission queue in your program as an instance of the ConcurrentLinkedQueue class. 3.5.2 Timeout Task Recall from Assignment 4 that to start and stop timeout, you need to schedule and cancel the corresponding timer task. There is only one active timer task at any given time, which could be accessed simultaneously by both the sending and receiving threads when starting or canceling timeouts. To prevent this situation, you have to synchronize access to the timer task. If you have followed my recommendation from Assignment 4 to define two helper methods to start and stop the timer, then all you have to do is to define these two methods as being synchronized methods: synchronized startTimer(); synchronized stopTimer(); Then Java ensures that only one of them can be executed at any point in time, effectively preventing them from being executed concurrently. You are of course not limited to this approach and can use other mechanisms (such as locks) to synchronize access to the timer task in your program. 3.6 Design Requirements Your client design should be based on the following principles: β€’ Segment Payload: Create segments with the maximum payload size for good performance. Only the last segment from the client to the server may not carry sufficient data to be of maximum size. β€’ Parallel Design: The three processes in charge of sending data segments, receiving ACKs, and re-transmissions must be implemented to run concurrently, i.e., in separate threads. 4 Software Interfaces The class Segment and the server program ftpserver are reused from Assignment 4. The server is implemented so that it can work with Stop-and-Wait as well as Go-Back-N protocol. 4.1 Method Signatures The required method signatures for class GoBackFtp are provided to you in the source file GoBackFtp.java. There are two methods that you need to implement, namely a constructor and method send. Refer to the Javadoc documentation provided in the source file for more 5 Assignment 5 CPSC 441 information on these methods. 4.2 FtpSegment Class This class defines the structure of the segments exchanged between the sender (i.e., client) and receiver (i.e., server). Read the Javadoc documentation of the class for how to use it. Note that both data packets and ACKs are of type FtpSegment. Segments that go from the sender to receiver carry data, while segments that come from the receiver are ACKs that do not carry any data. 4.3 Exception Handling Your implementation should include exception handling code to deal with all checked exceptions in your program. This includes catching the exceptions and printing exception messages (or the stack trace) to the standard system output. After that, clean up, close all streams and sockets and return from the send method. 4.4 Running Your Code A driver class named GoBackDriver is provided on D2L to demonstrate how we are going to run your code. Read the inline documentation in the source file GoBackDriver.java for detailed information on how to use the driver class. Moreover, you can download the server program that implements the service side of the protocol from D2L. The server program is provided in a jar file named ftpserver.jar. The server comes with a README which includes instructions on how to run it. Although you can check the transferred file in the working directory of the server for correctness, you should also correlate the output of your program with that of the server to verify correct protocol implementation. For example, you can correlate packet drops at the server with timeouts at the client, which should match. 4.5 Console Output Add print statements (using System.out.println) in your code to print the following information on the console: 1. send – every time the client sends a segment to the server. 2. ack – every time the client receives an ACK. 3. retx – every time a segment is re-transmitted due to timeout. 4. timeout – every time a timeout happens at the client. In the above, refers to the sequence number of the relevant data or ACK segment. Do not directly print anything else to the console beyond exception messages and the above information. For debugging purposes, you can use the global logger object defined in the driver class, whose level can be set using the command line option -v. Refer to the driver class 6 Assignment 5 CPSC 441 source file for more information. The logger can be used to write messages to console during code development. 4.6 Design Document Prepare and submit a design document to describe the effect of window size on the performance of your program. Performance is defined as the time it takes to upload a given file to the server. Use file large.jpg and set server parameters as: Loss = 0 and Delay = 0. Notice that the server prints the amount of time it takes to complete the file transfer. Include a plot to show the relation between the performance of your FTP client and its window size. Experiment with a range of window sizes and explain your results. Follow the design document formatting requirements on D2L. Restrictions β€’ You are not allowed to modify the class and method signatures provided to you. However, you can (and should) implement additional methods and classes as needed in your implementation. β€’ You have to write your own code for sending and receiving UDP packets. Ask the instructor if you are in doubt about any specific Java classes that you want to use in your program. 7