Sie sind auf Seite 1von 3

Assignment #2: UDP file receiver

Although the wise thing to do is to use existing protocols whenever the task you want to do is solved 
by one of them we are about to do the opposite here. After all, this is just an excuse for you to do 
some coding. 

The Protocol
In order to submit some files to a certain server, users employ a simple UDP­based program that 
sends a given file to the server. The protocol used is quite simple and it does not allow to name the 
received file.

File transfer splits the original file as a sequence of 512 byte blocks.  The client starts sending the 
first block.  To signal the end of the file the client sends a datagram that contains the next block 
number but no data.  In the Figure 1 we can see that blocks from #1 to #4 seem to be same size, but 
the last data block, #5 is slightly smaller as it contains the last bytes of the file that happen to be less 
than 512 bytes. There is an extra datagram, #6, that contains no file data at all. The server detects 
this condition as the end of the file transfer. 

Original file

#0 #1 #2 #3 #4 #5 #6
Figure 1: File is split into a sequence of blocks. All of them equal size 
but maybe the last one.

Each datagram data starts with a four­byte block number. After receiving one block the receiver 
sends a datagram containing the same four bytes containing the block number. Upon receiving this, 
the client is allowed to send the next data block.

MSB        block number LSB

datagram data 
(up to 512 bytes)

Figure 2: Each one of the above blocks has 
this structure. Answers from the server do not 
contain any data, just the block number.

The client code is provided so you can concentrate on writing the server code. Please note that 
filename is not transferred and server just names each file with a sequence number with the syntax 
“received­###” where each '#' is a decimal digit. The first received file name will be “received­000”, 
the second “received­001” and so on. If more than 1000 files are received the filename will wrap 
around and some files will be overwritten. 

The server
Your work consist on creating the server code so it can handle a single client at a time (you might 
want to create a concurrent version able to handle several clients at a time if you like challenges 
though). The server has 10 seconds “give­up” timer so if any file upload operation runs amok the 
server will return to the “wait for a new file” state (the same as if the last upload ended 
successfully). 
It is suggested you use the method setSoTimeout(time_in_ms) of DatagramSocket's class to achieve 
a time­limited blocking call when calling to the receive() method. If you do nothing, receive() 
blocks forever till a datagram is received. However, by using the setSoTimeout() method you can 
limit the maximum amount of time receive() call will wait for an incoming datagram. Once the 
timeout period has expired an exception will be raised. You can catch that exception to handle the 
proper actions when the server times out. 

Some tips:
● Assume that files are no larger than 2.199.023.255.552 bytes.
● Please add your full name as a comment in the first line of code.
● Send your server's source code using the provided client to my server msanchez.upv.es.
● In case of lost datagram the server will recover itself because the timer, but the client will 
hang. This is the expected behavior.
● Remember that method getAddress from DatagramPacket class provides you the source 
address the datagram was received from. 
● If the server receives a datagram with a number different than the expected block number it 
has to abort the current transfer, returning to the “wait for a new file” status.

Due date
This work is due by Monday January, 15th, 2007. 
The client code
import java.net.*;
import java.io.*;

public class A2client {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(8888);
        int bytes, block = 0;
        InetAddress dir = InetAddress.getByName(args[0]);    // destination address
        FileInputStream fis = new FileInputStream(args[1]);// origin file to be transmitted
        byte[] buffer = new byte[512+4];
        while((bytes = fis.read(buffer,4,512)) > ­1 ) {
            System.out.println( "Sending block = " + block);
            intToByteArray(buffer,block);
            DatagramPacket p = new DatagramPacket(buffer, bytes+4, dir, 7777);
            ds.send(p);                                                 // send datagram
            ds.receive(p);                                                // wait for answer
            if(block != byteArrayToInt(buffer) ) {
                System.out.println("Protocol error ... exiting the program");
                System.exit(10);
            }
            block++;
        }    // done with the file, let's signal the end of transfer (no wait for ACK here)
        intToByteArray(buffer,block);
        DatagramPacket p = new DatagramPacket(buffer, 4, dir, 7777);
        ds.send(p);
    }
    
    // some magic to put and retrieve the block number from the buffer
    
    public static int byteArrayToInt(byte[] b) { // takes the first four bytes
        int value = 0;                                     // of the buffer and turns them
        for (int i = 0; i < 4; i++) {                 // into an integer value (32 bits)
            int shift = (4 ­ 1 ­ i) * 8;
            value += (b[i] & 0x000000FF) << shift;
        }
        return value;
    }
    
    public static void intToByteArray(byte [] b, int value) {
        for (int i = 0; i < 4; i++) {                // writes four bytes representing
            int offset = (b.length ­ 1 ­ i) * 8;// an integer value
            b[i] = (byte) ((value >>> offset) & 0xFF);
        }
    }
    

Das könnte Ihnen auch gefallen