Results 1 to 5 of 5
  1. #1
    ladesidude is offline Member
    Join Date
    Oct 2008
    Posts
    2
    Rep Power
    0

    Question Reliable Data Transfer Protocol

    Hi. I am new to java forums and new to Java Programming as well. Presently am pursuing my software engineering degree. I have an assignment on using doing reliable data transfer using unreliable data transfer protocols. I will insert the code that I have so far and then the problem that I am having:

    Reliablesocket.java

    Java Code:
    /*
     * ReliableSocket.java
     *
     * Created on October 10, 2008, 4:28 PM
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
    
    import java.io.IOException;
    import java.net.*;
    
    /**
     * A socket that implements reliable communication over an UnreliableSocket.
     *
    */
    public class ReliableSocket
    {
        // The unreliable socket we will rely on to try to implement
        // reliable communcation.
        private UnreliableSocket uSock;
    
        // An unreliable packet we will use anytime we need to send
        // something.
        private UnreliablePacket sendPacket;
    
        // The byte buffer for the UnreliablePacket for sending
        private byte[] sendBuf;
    
        // An unreliable packet we will use anytime we need to
        // receive something.
        private UnreliablePacket recPacket;
    
        // A byte buffer for the UnreliablePacket for receiving
        private byte[] recBuf;
    
        // The number of milliseconds to wait for and acknowledgement
        // before resending a packet.
        private int ackWaitTime;
    
        // CHANGE:  Add extra necessary fields here to keep track
        //          of sequence numbers.
    	private byte ack,seqnum; 
        /*
         * Initialized all the additional fields of the class
         * (besides the UnreliableSocket).
         */
        private void allButSocket()
        {
            sendBuf = new byte[16];
            recBuf = new byte[16];
            sendPacket = new UnreliablePacket(sendBuf, 16);
            recPacket = new UnreliablePacket(recBuf, 16);
    		// CHANGE:  Add extra initialization code for any
    		//         fields you decide to add to the class.
    		ack = 0; //positive acknowledgement
    		seqnum = 0; //beginning
    
            
        }
        
        /**
         * Creates a new instance of ReliableSocket bound to an available port
         */
        public ReliableSocket() throws SocketException
        {
            uSock = new UnreliableSocket();
            allButSocket();
        }
        
        
        /**
         * Creats a new instance of ReliableSocket bound to a given port
         *
         * @param port the port on which to listen with this socket
         */
        public ReliableSocket(int port) throws SocketException
        {
            uSock = new UnreliableSocket(port);
            allButSocket();
        }
               
        /**
         * Set the amount of time before giving up and retransmitting when sending.
         *
         * @param time the time to wait before retransmitting in milliseconds
         */
        public void setAckWaitTime(int time)
        {
            ackWaitTime = time;
        }
        
        public void send(ReliablePacket packet) throws IOException
        {
            // CHANGE:  Use data in reliable packet to construct an unreliable packet.
            //          Add a sequence number to the packet.
            //          Keep sending the packet until you receive a matching
            //              acknowledgement.
            //          Don't forget to make use of timeouts in case the packet is lost.
    
    		sendBuf = packet.getData(); //get data
    		sendBuf[2] = seqnum;// add sequence number; 
    		sendPacket.setData(sendBuf);
    		sendPacket.setAddress(packet.getAddress());
    		sendPacket.setPort(packet.getPort());
    		sendPacket.setLength(packet.getLength());
    		
    		if (sendBuf[1] != ack)
    		{
    			System.out.println("acknowledgements didnt match.");
    			System.out.println("Sending = " + sendBuf[0]);
    			System.out.println("Acknowledgement in sending side = " + sendBuf[1]);
    			
    		}
    		else
    		{
    			//uSock.send(sendPacket);
    			System.out.println("sending = " + sendPacket.getData()[0]);
    			System.out.println("Acknowledgement on sending side = " + sendPacket.getData()[1]);
    
    			if (ack == 0)
    			{
    				ack = 1;
    			}
    			else
    			{
    				ack = 0;
    			}
    		}
    		uSock.send(sendPacket);
    		
        }
    
        /**
         * Waits to receive a packet.
         *
         * @param packet the object into which to store the received packet.
         */
        public void receive(ReliablePacket packet) throws IOException
        {
            // CHANGE:  Wait for an unreliable packet.
            // Check to make sure the sequence number is correct.
            // If it is, use the data to fill in the ReliablePacket
            // and send back an acknowledgement.
            // Think about what you need to do if it is not the correct
            // sequence number.
    
    		
    		recBuf = packet.getData();
    		recBuf[1] = ack;
    		recPacket.setData(recBuf);
    		recPacket.setAddress(InetAddress.getLocalHost());
    		recPacket.setPort(packet.getPort());
    		recPacket.setLength(packet.getLength());   
    		
    
    		if (recBuf[2] == seqnum)
    		{
    			if (seqnum == 0)
    			{
    				seqnum = 1;
    			}
    			else
    			{
    				seqnum = 0;
    			}
    			recBuf[2] = seqnum;
    			System.out.println("Sequence numbers matched.");
    			System.out.println("Received = " + recBuf[0]);
    			System.out.println("Acknowledgement in receiving side = " + recBuf[1]);
    
    		}
    		else //sequence numbers dont match
    		{
    			System.out.println("Sequence numbers didnt match");
    			System.out.println("Received = " + recBuf[0]);
    			System.out.println("Acknowledgement in receiving side = " + recBuf[1]);
    			uSock.send(recPacket);
    			
    		}
    
    		uSock.setSoTimeout(2000);
    		uSock.receive(recPacket);
    	}
    
        /**
         * A public helper function that copies part of one byte array into another byte array.
         *
         * @param dst the destination byte array
         * @param dstOff the position in the destination array at which to start copying
         * @param src the source byte array
         * @param srcOff the position in the source array from which to start copying
         * @param length the number of bytes to copy over
         */
        public static void arrayCopy(byte[] dst, int dstOff, byte[] src, int srcOff, int length)
        {
            if (srcOff < 0)
                throw new RuntimeException("Internal arrayCopy error: negative srcOff");
            if (dstOff < 0)
                throw new RuntimeException("Internal arrayCopy error: negative dstOff");
            if (length < 0)
                throw new RuntimeException("Internal arrayCopy error: negative srcOff");
            if (srcOff + length > src.length)
                throw new RuntimeException("Internal arrayCopy error: out of bounds on src array");
            if (dstOff + length > dst.length)
                throw new RuntimeException("Internal arrayCopy error: out of bounds on dst array");         
            for(int i = 0; i < length; i++)
                dst[dstOff+i] = src[srcOff+i];
        }
    
    }
    In the above, the Send and Receive part is giving me problems, when I run the program, neither of the parts give me any output and time out. I will now post the helper and tester classes.

    UnreliableSocket.java
    Java Code:
    /*
     * UnreliableSocket.java
     *
     * Created on October 7, 2008, 2:16 PM
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
    
    import java.util.Random;
    import java.io.IOException;
    import java.net.*;
    /**
     * A UDP like socket that randomly failes to send some percentage of the packets
     * it is asked to send.
     *
     */
    public class UnreliableSocket
    {
        
    
        private static double dropRate = 0.01;
        private DatagramSocket sock;
        private Random r;
    
         
        /**
         * Creates a new instance of UnreliableSocket bound to an available port
         */
        public UnreliableSocket() throws SocketException
        {
            sock = new DatagramSocket();
            r = new Random();
            r.setSeed(System.currentTimeMillis());
        }
        
        /**
         * Creats a new instance of UnreliableSocket bound to a given port
         * 
         * 
         * @param port the port on which to listen with this socket
         */
        public UnreliableSocket(int port) throws SocketException
        {
            sock = new DatagramSocket(port);
            r = new Random();
            r.setSeed(System.currentTimeMillis());
        }
        
        /**
         * Sends the packet p to the destination contained in the packet
         * 
         * @param packet the packet to send 
         */
        public void send(UnreliablePacket packet) throws IOException
        {
            if (r.nextDouble() > dropRate)
                sock.send(packet.dp);
        }
    
        /**
         * Waits to receive a packet.
         *
         * @param packet the object into which to store the received packet.
         */
        public void receive(UnreliablePacket packet) throws IOException
        {
            sock.receive(packet.dp);
            
            /*
            p.setDstIp(sock.getLocalAddress());
            p.setDstPort(sock.getLocalPort());
            p.setSrcIp(dp.getAddress());
            p.setSrcPort(dp.getPort());
            p.setDataLength(dp.getLength());
            
        System.out.println("NetSimSocket.receive: from " + p.getSrcIp() + ":" + p.getSrcPort());
        System.out.println("NetSimSocket.receive: to   " + p.getDstIp() + ":" + p.getDstPort());
        System.out.println("NetSimSocket.receive: data " + (new String(p.data, 0, p.getDataLength())));   
             **/
        }
        
        /**
         * Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.
         * With this option set to a non-zero timeout, a call to receive() for this
         * UnreliableSocket will block for only this amount of time. If the timeout
         * expires, a java.net.SocketTimeoutException is raised, though the
         * UnreliableSocket is still valid. The option must be enabled prior to
         * entering the blocking operation to have effect. The timeout must
         * be > 0. A timeout of zero is interpreted as an infinite timeout. 
         *
         * @param timeout the specified timeout in milliseconds
         * @throws SocketException if there is an error in the underlying protocol, such as an UDP error
         */
        public void setSoTimeout(int timeout) throws SocketException
        {
            sock.setSoTimeout(timeout);
        }
    
        /**
         * Retrieve setting for SO_TIMEOUT. 0 returns implies that the option is
         * disabled (i.e., timeout of infinity).
         *
         * @return the setting for SO_TIMEOUT
         * @throws SocketException if there is an error in the underlying protocol, such as an UDP error
         */
        public int getSoTimeout() throws SocketException
        {
            return sock.getSoTimeout();
        }
    }
    ReliablePacket.java
    Java Code:
    /*
     * ReliablePacket.java
     *
     * Created on October 10, 2008, 4:28 PM
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
    
    import java.net.*;
    /**
     *
    */
    public class ReliablePacket
    {
        byte[] buf;
        int length;
        InetAddress address;
        int port;
        
        
        /**
         * Creates a new instance of ReliablePacket
         *
         * @param buf the buffer for the packet.  It can be at most size 8.
         * @param length the number of bytes in the buffer to use for sending or
         * receiving.  It must be positive and no larger than the buffer.
         */
        public ReliablePacket(byte[] buf, int length)
        {
            if (buf.length > 8)
                throw new RuntimeException("Buffer must be no larger than 8 bytes");
            if (length < 0)
                throw new RuntimeException("Length cannot be negative");
            if (length > buf.length)
                throw new RuntimeException("Length cannot be bigger than buf.length");
            this.length = length;
            this.buf = buf;
        }
        
    
        /**
         * Returns the IP address of the machine to which this packet is being
         * sent or from which the packet was received.
         *
         * @return the IP address of the machine to which this packet is being
         * sent or from which the packet was received.
         */
        public InetAddress getAddress()
        {
            return address;
        }
        
        /**
         * Returns the data buffer.
         *
         * @return the data buffer in the packet.
         */
        public byte[] getData()
        {
            return buf;
        }
        
        
        /**
         * Returns the length of the data to be sent or the length of the data received.
         *
         * @return the length of the data to be sent or the length of the data received
         */
         public int getLength()
        {
            return length;
        }
        
        
        /**
         * Returns the port number on the remote host to which this datagram is
         * being sent or from which the datagram was received.
         *
         * @return the port number on the remote host to which this datagram is
         * being sent or from which the datagram was received.
         */
        public int getPort()
        {
            return port;
        }
     
        /**
         * Sets the IP address of the machine to which this datagram is being sent.
         *
         * @param iaddr the IP address of the machine to which this datagram is
         * being sent.
         */
        public void setAddress(InetAddress iaddr)
        {
            address = iaddr;
        }
        
        
        /**
         * Set the data buffer for this packet. 
         *
         * @param buf the data buffer to use for this packet.  The size of the
         * buffer cannot be larger than 8.
         */
        public void setData(byte[] buf)
        {
            if (buf.length > 8)
                throw new RuntimeException("Buffer must be no larger than 8 bytes");
            this.buf = buf;
        }
        
         /**
         * Set the length for this packet. 
         *
         * @param length the length to set for this packet
         */
        public void setLength(int length)
        {
            if (length < 0)
                throw new RuntimeException("Length cannot be negative");
            if (length > buf.length)
                throw new RuntimeException("Length cannot be greater than buffer size");
            this.length = length;
        }
        
        /**
         * Sets the port number on the remote host to which this datagram is being
         * sent. 
         *
         * @param iport the port number
         */
        public void setPort(int iport)
        {
            port = iport;
        }
    
    }
    UnreliablePacket.java

    Java Code:
    /*
     * UnreliablePacket.java
     *
     * Created on October 7, 2008, 2:29 PM
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
    
    import java.net.*;
    
    /**
     * A packet that can be sent via an UnreliableSocket
     *
     * @author WMarrero
     */
    public class UnreliablePacket
    {
        DatagramPacket dp;
        
        /**
         * Creates a new instance of UnreliablePacket
         * 
         * 
         * @param buf the buffer for the packet.  It can be at most size 16.
         * @param length the number of bytes in the buffer to use for sending or
         * receiving.  It must be positive and no larger than the buffer.
         */
        public UnreliablePacket(byte[] buf, int length)
        {
            if (buf.length > 16)
                throw new RuntimeException("Buffer must be no larger than 16 bytes");
            if (length < 0)
                throw new RuntimeException("Length cannot be negative");
            if (length > buf.length)
                throw new RuntimeException("Length cannot be bigger than buf.length");
            dp = new DatagramPacket(buf, length);
        }
        
        /**
         * Returns the IP address of the machine to which this datagram is being
         * sent or from which the datagram was received.
         *
         * @return the IP address of the machine to which this datagram is being
         * sent or from which the datagram was received.
         */
        public InetAddress getAddress()
        {
            return dp.getAddress();
        }
         
        /**
         * Returns the data buffer.
         *
         * @return the data buffer in the packet.
         */
        public byte[] getData()
        {
            return dp.getData();
        }
     
        /**
         * Returns the length of the data to be sent or the length of the data received.
         *
         * @return the length of the data to be sent or the length of the data received
         */
        public int getLength()
        {
            return dp.getLength();
        }
        
        /*
        int getOffset() 
              Returns the offset of the data to be sent or the offset of
              the data received.
         **/
        
        /**
         * Returns the port number on the remote host to which this datagram is
         * being sent or from which the datagram was received.
         *
         * @return the port number on the remote host to which this datagram is
         * being sent or from which the datagram was received.
         */
        public int getPort()
        {
            return dp.getPort();
        }
         
        /*
         SocketAddress getSocketAddress() 
             Gets the SocketAddress (usually IP address + port number) of the
             remote host that this packet is being sent to or is coming from. 
         **/
         
        /**
         * Sets the IP address of the machine to which this datagram is being sent.
         *
         * @param iaddr the IP address of the machine to which this datagram is
         * being sent.
         */
        public void setAddress(InetAddress iaddr)
        {
            dp.setAddress(iaddr);
        }
    
        /**
         * Set the data buffer for this packet. 
         *
         * @param buf the data buffer to use for this packet.  The size of the
         * buffer cannot be larger than 16.
         */
        public void setData(byte[] buf)
        {
            dp.setData(buf);
        }
        
        /*
    
         * Set the data buffer for this packet. 
         *
         * @param buf the buffer to set for this packet
         * @param offset the offset into the data
         * @param length the length of the data and/or the length of the buffer
         * used to receive data 
    
        void setData(byte[] buf, int offset, int length)
        {
            dp.setData(buf, offset, length);
        }
         **/
    
        /**
         * Set the length for this packet. 
         *
         * @param length the length to set for this packet
         */
        public void setLength(int length)
        {
            if (length < 0)
                throw new RuntimeException("Length cannot be negative");
            if (length > dp.getData().length)
                throw new RuntimeException("Length cannot be greater than buffer size");
            dp.setLength(length);
        }
        
        /**
         * Sets the port number on the remote host to which this datagram is being
         * sent. 
         *
         * @param iport the port number
         */
        public void setPort(int iport)
        {
            dp.setPort(iport);
        }
    }

    Tester classes:

    ReliableTestSender.java
    Java Code:
    import java.net.InetAddress;
    /**
     * Summary description for Program Reliable sender
     */
    public class Program
    {
    	public static void main(String[] args) throws Exception
    	{
    		byte[] buffer = new byte[8];
    		ReliablePacket p = new ReliablePacket(buffer, 8);
    		ReliableSocket s = new ReliableSocket();
    		p.setAddress(InetAddress.getLocalHost());
    		p.setPort(6767);
    		p.setLength(1);
    		for (int i = 0; i < 10; i++)
    		{
    			buffer[0] = (byte)(0xFF & i);
    			s.send(p);
    		}
    	}
    }
    
    
    ReliableTestReceiver.java
    [CODE]
    public class ReliableTestReceiver
    {
        
        public static void main(String[] args) throws Exception
        {
            byte[] buffer = new byte[8];
            ReliablePacket p = new ReliablePacket(buffer, 8);
            ReliableSocket s = new ReliableSocket(6767);
            byte expected = 0;
            for (int i = 0; i < 100; i++) {
                s.receive(p);
                if (expected != buffer[0]) {
                    System.out.printf("Lost byte number %d%n", i);
                    System.exit(1);
                }
                else {
    			System.out.printf("Received byte number %d%n", i);	                if (i % 100 == 99)
                        System.out.print(i);
                    expected++;
                }
            }
            System.out.println("FINISHED TEST");
        }
     
    }
    [/CODE]
    Thanks all for your help:)
    Last edited by ladesidude; 10-26-2008 at 05:42 AM.

  2. #2
    fishtoprecords's Avatar
    fishtoprecords is offline Senior Member
    Join Date
    Jun 2008
    Posts
    571
    Rep Power
    6

    Default

    The code looks decent, that's a good start. When you say "In the above, the Send and Receive part is giving me problems, when I run the program, neither of the parts give me any output and time out."

    does this mean that both the "reliable" and "unreliable" versions give you the same problems?

    Do you get any errors? or just that it doesn't work?

    For a lot of networking programs, I write two main programs, one to send and a second to receive. This helps isolate the problems.

  3. #3
    ladesidude is offline Member
    Join Date
    Oct 2008
    Posts
    2
    Rep Power
    0

    Default

    Hi,

    Well, ReliableSocket.java uses the unreliableSocket.java and unreliablePacket.java, so its the unreliable part thats giving me the problem.

    As for writing 2 separate programs, the tester programs are just for that. I have ReliableTestSender.java and ReliableTestReceiver.java, they are Reliable because I use the Reliablesocket.java.

    I will also post an update to my code for further review and help.

    Thanks

  4. #4
    fishtoprecords's Avatar
    fishtoprecords is offline Senior Member
    Join Date
    Jun 2008
    Posts
    571
    Rep Power
    6

    Default

    Try writing a version of Reliable that just uses TCP/IP, which is reliable, and get that to work first. Then debug it using the datagram code

  5. #5
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    19

    Default

    Quite unusual exercise this is. Since you have much reliable communication protocol, as said in the last post of fishtoprecords TCP/IP, why you want to use an unreliable protocol. ;)

    Anyway, as fishtoprecords says try with the TCP first.

Similar Threads

  1. Fast Data Transfer 0.9.1
    By Java Tip in forum Java Software
    Replies: 0
    Last Post: 04-24-2008, 06:41 PM
  2. Fast Data Transfer 0.8.5
    By JavaBean in forum Java Software
    Replies: 0
    Last Post: 11-12-2007, 06:11 PM
  3. Fast Data Transfer 0.6.7
    By Jamie in forum Java Software
    Replies: 0
    Last Post: 06-14-2007, 02:55 PM
  4. Fast Data Transfer 0.6.4
    By levent in forum Java Software
    Replies: 0
    Last Post: 05-21-2007, 10:11 AM
  5. Fast Data Transfer 0.6.4
    By levent in forum Java Software
    Replies: 0
    Last Post: 05-20-2007, 08:55 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •