package nfs; import java.io.IOException; import java.io.InterruptedIOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * this is used to call a server and wait for a response, taking into account that messages can be lost. * The calling message is supposed to be in a datagram packet and the answer itself is given back as a datagram packet * * @author marcod * */ public class UDPServerComm { /** * parameters to reach the server */ InetAddress serverAddress = null; int serverPort = 0; DatagramSocket ds = null; /** * number of retries when a message fails to get an aswer */ int retries = 10; /** * timeout used to wait an answer from the server */ int timeoutSeconds = 5; /** * limit of the size of the datagram packet payload (just for this exercise) */ public static final int LIMIT = 8192; /** * constructor, intializes the parameters needed to communicate with the server: the address and the port * @param serverName name of the machine running the server * @param port port used by the server to listen messages */ public UDPServerComm(String serverName, int port) { try { serverAddress = InetAddress.getByName(serverName); serverPort = port; ds = new DatagramSocket(); } catch(Exception e) { e.printStackTrace(); } return; } /** * used to set the number of times we have to retransmit before actually failing * @param n number of time to retransmit */ public void setRetries(int n) { retries = n; } /** * sets the seconds used before timeouting a request * @param n the number of seconds the answer is awaited before getting the timeout */ public void setTimeoutSeconds(int n) { timeoutSeconds = n; } /** * this is the main method: sends the server the datagram packet and waits for an answer, setting proper timeouts * and retransmitting, if the case * @param dp the datagram to be sent to the server * @return the datagram aswered by the server */ public DatagramPacket call(DatagramPacket dp) { DatagramPacket answer = new DatagramPacket(new byte[LIMIT], LIMIT); // prepare the datagram to be sent dp.setAddress(serverAddress); dp.setPort(serverPort); try { // the start waiting for an answer boolean done = false; // set retries to default value int nretry = retries; // set timeout ds.setSoTimeout(timeoutSeconds*1000); do { try { // now send the datagram ds.send(dp); // wait for the answer ds.receive(answer); // got! we are done! done = true; } catch(InterruptedIOException e) { // if the receive timeouts ... nretry--; // decrease retry no. if(nretry == 0) // in case we reached the limit return null; // just return a null } } while(!done); } catch (IOException e) { e.printStackTrace(); } return answer; } }