/* * Copyright (c) 2001 Matthew Feldt. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided the copyright notice above is * retained. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES. */ /** * UDPReceive.java * * Java Examples In A Nutshell Copyright (c) 2000 David Flanagan * Exercise 5-6: * Modify the UDPSend and UDPReceive programs of Example 5-11 and Example * 5-12 so that UDPReceive sends an acknowledgement when it receives a data- * gram, and so that UDPSend doesn't exit until it receives the acknowledgement. * The acknowledgement should itself be a datagram and can contain any data * you desire. (You could use the checksum classes of the java.util.zip pack- * age, for example, to compute a checksum of the received data and send this * back in the acknowledgement packet.) Use the setSoTimeout() method of * DatagramSocket so that UDPSend doesn't wait for more than a few seconds to * receive the acknowledgment. If the acknowledgment packet is not received * before the timeout, UDPSend should assume that the original packet got lost * and was not received. Your modified UDPSend should try to resend the packet * once or twice , and if it still doesn't receive an acknowledgment, it should * exit with an error message. * * @author Matthew Feldt * @version 1.0, 03/08/2001 13:41 */ package com.feldt.examples.net; import java.io.*; import java.net.*; import java.util.zip.*; public class UDPReceive { static final String USAGE = "Usage: java UDPReceive "; static final int ackPort = 9999; static final int BUFFER_SIZE = 2048; public static void main(String args[]) { CRC32 crc; String msg, ack; try { if (args.length != 1) throw new IllegalArgumentException("wrong number of args"); // get port from the command line int port = Integer.parseInt(args[0]); // input buffer, data exceeding BUFFER_SIZE will be discarded byte[] buffer = new byte[BUFFER_SIZE]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); DatagramSocket dsocket = new DatagramSocket(port); for(;;) { dsocket.receive(packet); // wait for datagrams msg = new String(buffer, 0, packet.getLength()); // calculate message checksum and create an acknowledgment crc = new CRC32(); crc.update(msg.getBytes()); ack = packet.getAddress().getHostName() + ":" + crc.getValue(); // print status System.out.println("Received\n message : " + msg); System.out.println(" crc : " + crc.getValue()); System.out.println(" from : " + packet.getAddress().getHostName() + ":" + packet.getPort()); // send acknowledgment InetAddress address = packet.getAddress(); DatagramPacket ackPacket = new DatagramPacket(ack.getBytes(), ack.getBytes().length, address, ackPort); // create datagram socket, send packet through it, close it. DatagramSocket ackSocket = new DatagramSocket(); ackSocket.send(ackPacket); ackSocket.close(); System.out.println("Acknowledgment\n message : " + ack); // reset the length of the packet before reusing it. // prior to Java 1.1, we'd just create a new packet each time. packet.setLength(buffer.length); } } catch (Exception e) { System.err.println(e); System.err.println(USAGE); System.exit(-1); } } }