Subversion Repositories programming

Rev

Rev 216 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
213 ira 1
/*******************************************************************************
2
 * File: P2_Client.java
3
 * Author: Ira W. Snyder (devel@irasnyder.com)
4
 * License: GNU General Public License v2
5
 * Class: CS380 - Computer Networking
6
 *
7
 * Assignment: Project #2
8
 * Date Last Modified: 2006-02-05
9
 *
10
 * Purpose: Implement a simple client allowing the user to send datagrams
11
 * to P2_Server, which will decode them from 4B to 5B encoding. The client
12
 * will retransmit any packets that do not recieve a reply.
13
 ******************************************************************************/
211 ira 14
 
15
import java.io.*;
16
import java.net.*;
17
import java.util.*;
18
 
19
public class P2_Client
20
{
21
    private static int soTimeout = 3000; // 3000 ms timeout = 3 sec
22
    private static DatagramSocket socket;
23
    private static DatagramPacket packet;
24
    private static int portNumber = 1337;
216 ira 25
    private static int packetNum = 0;
211 ira 26
 
217 ira 27
    public static boolean verifyInput (String s)
28
    {
29
        int i;
30
 
31
        // Check for QUIT message
32
        if (s.equals("QUIT"))
33
            return true;
34
 
35
        // If it's not a QUIT, it must be 0's and 1's only
36
        for (i=0; i<s.length; i++)
37
            if (!(s.charAt(i) == '0' || s.charAt(i) == '1'))
38
                return false;
39
 
40
        // Everything was a 0 or 1, good!
41
        return true;
42
    }
43
 
213 ira 44
    /**
45
     * Method: readPacket()
46
     * Purpose: Read a packet on the currently opened DatagramSocket,
47
     * and return it as a String.
48
     */
215 ira 49
    public static P2_Packet readPacket ()
211 ira 50
    {
215 ira 51
        byte[] buf = new byte[256];
211 ira 52
        packet = new DatagramPacket (buf, buf.length);
53
 
54
        try {
55
            socket.receive (packet);
56
        } catch (SocketTimeoutException e) {
57
            System.out.println ("Read timed out, requesting retransmit");
58
            return null;
59
        } catch (PortUnreachableException e) {
60
            System.out.println ("Caught PortUnreachableException, are you" +
61
                                " sure the server is running?");
62
            System.exit(1);
63
        } catch (IOException e) {
64
            System.out.println ("Caught exception in readPacket()");
65
            e.printStackTrace();
66
            return null;
67
        }
68
 
215 ira 69
        return new P2_Packet (packet.getData());
211 ira 70
    }
213 ira 71
 
72
    /**
73
     * Method: writePacket()
74
     * Purpose: Send a packet to localhost:portNumber.
75
     */
216 ira 76
    public static boolean writePacket (byte type, byte[] data, int packetNum)
211 ira 77
    {
215 ira 78
        InetAddress address = null;
211 ira 79
        int port = portNumber;
80
 
215 ira 81
        try {
82
            address = InetAddress.getLocalHost();
83
        } catch (UnknownHostException e) {
84
            System.err.println ("Caught UnknownHostException in writePacket(), " +
85
                                "are you sure the system is working?");
86
            System.exit(1);
87
        }
88
 
216 ira 89
        byte[] buf = P2_Packet.createPacket (type, data, packetNum);
211 ira 90
        packet = new DatagramPacket (buf, buf.length, address, port);
91
 
92
        try {
93
            socket.send (packet);
94
        } catch (PortUnreachableException e) {
95
            System.out.println ("Caught PortUnreachableException, are " +
96
                                "you sure the server is running?");
97
            System.exit(1);
98
        } catch (IOException e) {
99
            System.out.println ("Caught exception in writePacket()");
100
            e.printStackTrace();
101
            return false;
102
        }
103
 
104
        return true;
105
    }
106
 
213 ira 107
    /**
108
     * Method: guaranteedTransmit()
109
     * Purpose: A wrapper around readPacket() and writePacket() that implements
217 ira 110
     * a reliable transmit mechanism.
213 ira 111
     */
215 ira 112
    public static P2_Packet guaranteedTransmit (byte type, byte[] data)
213 ira 113
    {
215 ira 114
        P2_Packet reply;
213 ira 115
        int retries = 0;
116
 
216 ira 117
        writePacket (type, data, packetNum);
215 ira 118
        reply = readPacket ();
213 ira 119
 
215 ira 120
        while (reply == null)
213 ira 121
        {
122
            System.err.println ("Packet lost, retransmitting...");
216 ira 123
            writePacket (type, data, packetNum);
215 ira 124
            reply = readPacket ();
213 ira 125
            retries++;
126
        }
127
 
216 ira 128
        if (retries > 0)
129
            packetNum = 0; //reset packetNum
130
 
131
        packetNum++;
213 ira 132
        return reply;
133
    }
134
 
217 ira 135
    /**
136
     * Method: guaranteedTransmit()
137
     * Purpose: A simplified version of the guaranteedTransmit() above.
138
     */
215 ira 139
    public static P2_Packet guaranteedTransmit (byte type)
140
    {
141
        byte[] pData = { 0 };
142
 
143
        return guaranteedTransmit (type, pData);
144
    }
145
 
213 ira 146
    /**
147
     * Method: main()
148
     * Purpose: This will accept input from the user, and attempt to send it
149
     * to the corresponding server, which will convert the messages from 4B
150
     * to 5B encoding.
151
     */
211 ira 152
    public static void main (String[] args) throws Exception
153
    {
212 ira 154
        int dropHowMany = 0;
211 ira 155
        socket = new DatagramSocket();
156
        socket.connect (InetAddress.getLocalHost(), portNumber);
157
        socket.setSoTimeout (soTimeout);
158
 
159
        BufferedReader kbd = new BufferedReader (
160
                                 new InputStreamReader (
161
                                     System.in));
162
 
212 ira 163
        try {
164
            dropHowMany = Integer.parseInt(args[0]);
165
        } catch (ArrayIndexOutOfBoundsException e) {
166
            System.err.println ("You need to call the program with \'java P2_Client <num>\'");
167
            System.exit(1);
168
        }
211 ira 169
 
215 ira 170
        String msg;
171
        byte[] pData = { (byte)dropHowMany };
172
        P2_Packet reply = guaranteedTransmit (P2_Packet.DROP, pData);
212 ira 173
 
215 ira 174
        if (reply.getPacketType() != P2_Packet.DROP)
213 ira 175
        {
176
            System.err.println ("Unable to inform the server how often to drop packets");
177
            System.exit(1);
178
        }
179
 
211 ira 180
        System.out.print ("% decode: ");
213 ira 181
        msg = kbd.readLine();
211 ira 182
        boolean done = false;
183
 
184
        while (!done)
185
        {
215 ira 186
            if (msg.equals("QUIT"))
211 ira 187
            {
215 ira 188
                reply = guaranteedTransmit (P2_Packet.QUIT);
211 ira 189
                done = true;
190
                continue;
191
            }
215 ira 192
 
193
            reply = guaranteedTransmit (P2_Packet.TRANSREQ, P2_EncDec.convertToByteArray(msg));
211 ira 194
 
215 ira 195
            System.out.println ("-> reply: " + P2_EncDec.convertToString(reply.getPacketData()));
211 ira 196
            System.out.print ("% decode: ");
197
            msg = kbd.readLine();
198
        }
213 ira 199
 
200
        // Close the socket
201
        socket.close();
211 ira 202
    }
203
}
204