首页 > > 详细

CO2017 — Exercise 3 — Java Client-Server with Sockets

 
CO2017 — Exercise 3 — Java Client-Server with Sockets
 
Module evaluation time!
 
Please take a few minutes to complete the moduleevaluation forms for this and your other modules. 
 
Preamble
 
Some of these questions will be must be handed in forassessment by the end of Monday 29thApril. Detailed submission instructions will be addedin due course. 
 
Please check back here for last minute updates beforesubmitting your work 
  
In this page (and in other pages for this module): 
 
 
Pale yellow boxes indicate code or other material that shouldbe the contents of a file — you will generally use aneditor, such as Emacs, Scite or GEdit to enter/view the content.
 
 
Pale blue boxes indicate a place where you should be entering acommand, e.g. at a command prompt in a terminal window.
 
 
Pale pink boxes indicate interactive use, with the input you shouldtype in RED; other text is expectedoutput from a program.
 
Hints and asides are written in pink italics. 
 
Question 1 — Number SquareService
 
Your task is to write a pair of programs, client and server,to implement a number squaring service. This initally besimilar to the TimeServer/Clientexample discussed in lectures. 
 
You will need to choose a port to run your service on. To get a unique port number, try using your numericuid. "getent passwd " will tell youyour uid (and your gid).  
 
Client
 
The client uses a Socket to make a connection to theserver. Once connected, the client prompts the user for anumber (in the console; no need for a GUI), and sends it tothe server. The server responds with the square of thenumber, which the client will print on the screen. 
 
Keep going until the user submits the special number999. The client should send the special number, then shutdown. 
 
Server
 
Server listens for connections. When a connection is made, isshould create a handler Thread which waits for numbers to besent from the client. After receiving a number, it shouldcalculate the square and send it back to the client. 
 
Repeat until the client sends the special number 999. 
 
Extra features
•What happens if the client tries to connect and no serveris running? 
•What happens if one end just stops in the middle (clientnever sends another number; server never responds to arequest)? 
•Test it over two machines. Try running more than oneclient against one server. 
•Test your client with another person's server; and viceversa. 
 
Unassessed — solution 
 
 
Question 2 — Number Guessing Game
 
Before you start
 
Please take a few minutes to complete the moduleevaluation forms for this and your other modules. 
 
 
Introduction
  
This assessed exercise needs to be submitted by the morning ofMonday 29th April, using the usual handin system. 
 
The worksheet is presented in several phases to lead youtowards a working solution. If you do notmake it to the final phase, you should hand in as far as youhave managed. If you do make it to the finalphase, you only need to hand that in. 
 
The theme of the exercise is to produce a simple client/servertimed number guessing game. The server will: 
1.Start using command line arguments for: ◦port to listen on;
◦maximum number to use in the guessing game (forexample, a value of 143 means that the numbers to guesswill be between 1 and 143);
◦time limit for the guessing game (in seconds).
 
2.accept connections from clients (game players); recieveguesses from the clients (players) and respond suitably;stop the game if the client (player) guesses correctly, orif they run out of time. 
3. All timing is carried out on the server side. 
 
Meanwhile, the client program has to interact with both theserver and the player of the game: 
1.Start using command line arguments for: ◦hostname of the server;
◦port to connect to on the server.
 
2.Connect to the server on the specified host and port andplay the guessing game. Read guesses made by the player onthe terminal, and show the responses made by the server. 
3.Note that the client does not need tokeep track of any details of the game.
 
 
Protocol
 
Central to the exercise is the protocol for communicatingbetween the client and server. 
 
The message forms are shown here using String.format style specifications,followed by an example (inred) as it would appear in use. 
 
Client to server protocol
 
The protocol for messages from the client to the server isvery simple; there is only one form. 
 
("%s%n",m)53"m"is a string of input read from the user.
Typically the strings sent by the client will be numericvalues that represent the user's guesses. However, theclient does not need to perform anyvalidation on the values sent; this is up to theserver. 
 
Server to clientprotocol
 
There are 6 message forms that can be sent from the serverto the client. 
 
("START:%d:%d%n",max,time)START:100:15000Sent as the first message at the beginning of a newgame. "max" is the maximum value the targetnumber that the server is using. "time" is thetime limit, in milliseconds, for the game to be completed. 
("ERR:%d:%d%n",rem,turns)ERR:2396:5Sent if the time is not yet expired, and the lastmessage from the client was not suitable. In particular,if it was not an integer value between 1 and the maximumallowed. "rem" is a long value representing the amountof time (in milliseconds) remainingto complete the game; "turns" is the number of (valid)attempts so far made by the user. 
("HIGH:%d:%d%n",rem,turns)HIGH:8743:3Sent if the time is not yet expired and the lastmessage from the client was a value higher than thetarget. "rem" is a long value representing theamount of time (in milliseconds) remaining to complete thegame; "turns" is the number of (valid) attemptsso far made by the user. 
("LOW:%d:%d%n",rem,turns)LOW:11432:2Sent if time is not yet expired and the last messagefrom the client was a value lower than thetarget. "rem" is a long value representing theamount of time (in milliseconds) remaining to complete thegame; "turns" is the number of (valid) attemptsso far made by the user. 
("WIN:%d:%d%n",turns,target)WIN:8:93Sent if the time is not yet expired, and the lastmessage from the client was a correctguess. "turns" is the number of (valid) attemptsmade by the user; "target" is a the target value that was correctly guessed. 
("LOSE:%d:%d%n",turns,target)LOSE:11:93Sent if the time limit has been exceeded, regardlessof the last message received. "turns" is thenumber of (valid) attempts made by the user;"target" is the target that was not guessed. 
Packages
 
Write your code in java packages called"CO2017.exercsie3.uid.server" and"CO2017.exercsie3.uid.client"where uid isyour username in (lowercase).This will simplify the marking process. Toachieve this, you need to start each code file with a linelike one of these (replace uid with your ownusername, in lowercase). 
 
package CO2017.exercise3.uid.server;
 
package CO2017.exercise3.uid.client;
 
Server (link to javadoc)
 
NOW UPDATED
 
Check back for updates to the javadoc with more hints.
 
Remember to change your package name to your own username.
 
Client (link tojavadoc)
 
NOW UPDATED
 
Check back for updates to the javadoc with more hints.
 
Remember to change your package name to your own username.
 
 
Phase 0
 
Write a class GameState that can be used torecord the current state of a particular instance of thegame on the server side. 
 
Your code should satisfy the javadocspecification. But note that you do not need toimplement all features at once; the javadoc will make itclear that some features can be omitted until later phases. 
 
Phase 1
 
Write a simple, single thread server and client system thatcan play the game without worrying about the timelimit. (Where the protocol requires a "time" value to besent, just send a dummy value of 9999.) 
 
GuessGameServerclass
 
Should accept three command line arguments: 
1. port that the server should listenon;
2. max value that the target number canhave
3. time limit time limit (in seconds) forthe game (will be ignored in phase 1)
 
The server should listen for connections on the specifedport, and when a connection is made, play the numberguessing game: 
1.Generate a random target number between 1 and thespecified maximum
2.Send the "START" message to the client
3.Wait for and respond to the responses made by theclient as described in the protocol section.
4.Keep going without regard for the time limit until acorrect guess is made
5.End the game and wait for a new client to connect
 
GuessGameClientclass
 
Should accept two command line arguments: 
1. hostname that the server is running on;
2. port that the server is listeningon;
 
The client should make a connection to the specified hoston the specifed port and then follow the protocoldescribed above. 
 
When a game is over (which only happens when a correctguess is made in phase 1), the client should terminate. 
 
Phase 2
 
Extend your solution to Phase 1 so that the server canhandle multiple clients at the same time. There is still noneed to enforce the timing requirements in thisphase. (Where the protocol requires a "time" value to besent, just send a dummy value of 9999.) 
 
To do this you will split the bulk of the functionality ofthe previous GuessGameServer class to a newhandler class, called GuessGameServerHandler. 
 
Phase 3
 
Extend your solution to phase 2 so that it enforces thespecified time limit for games. 
 
This will require you to run an extra thread on the serverside for each game to monitor the time taken so far, and tofinish the game when it has gone on too long. 
 
In addition, you will need to limit the length of time thatthe server waits for clients to respond with a guess. 
 
Finally, you will also need to modify the client side sothat communication with the server runs in a separate threadto the local user input. In this way, when the time limit isreached and the server sends a message asynchronously, theclient can end the game. 
 
Example behaviour:
 
Example behaviour is shown for phase 3. In the exampleonly one game is taking place at a time; for phase 2onwards, games A, B and C could be interleaved. 
 
In particular you should note that the output shownon-screen by the client and server is not thesame as the protocol messages that are sentbetween the client and server using sockets. 
 
Phase 1/2would be similar, but games would always continue until acorrect guess is made. 
 
 
$ java CO2017.exercise3.gtl1.server.GuessGameServer 8111 100 20 
Starting GuessGame server (100, 20000) on port 8111
A connection : /127.0.0.1
A start watching
A target is 2
A 50 (HIGH)-15.8s/1
A 25 (HIGH)-12.6s/2
A 12 (HIGH)-9.9s/3
A 12 (HIGH)-4.4s/4
A 3 (HIGH)-2.2s/5
A - (LOSE)--0.0s/5
A 3 (LOSE)--0.0s/5
A Game over
B connection : /127.0.0.1
B start watching
B target is 80
B 50 (LOW)-17.5s/1
B 75 (LOW)-14.6s/2
B 87 (HIGH)-11.5s/3
B 81 (HIGH)-8.4s/4
B 78 (LOW)-5.8s/5
B 79 (LOW)-3.1s/6
B 80 (WIN)-1.4s/7
B Game over
C connection : /127.0.0.1
C target is 35
C start watching
C ** (ERR non-integer)-17.9s/0
C -10 (ERR out of range)-15.3s/0
C 5 (LOW)-11.7s/1
C 101 (ERR out of range)-8.1s/1
C ** (ERR non-integer)-2.5s/1
C - (LOSE)--0.0s/1
C 101 (LOSE)--0.0s/1
C Game over
^C
 
$ java CO2017.exercise3.gtl1.client.GuessGameclient localhost 8111
New guessing game. Range is 1..100. Time limit is 20.0s
Enter guess: 50
Turn 1: 50 was HIGH, 15.8s remaining
Enter guess: 25
Turn 2: 25 was HIGH, 12.6s remaining
Enter guess: 12
Turn 3: 12 was HIGH, 9.9s remaining
Enter guess: 12
Turn 4: 12 was HIGH, 4.4s remaining
Enter guess: 3
Turn 5: 3 was HIGH, 2.2s remaining
Enter guess:
Turn 5: target was 2 - LOSE
$ java CO2017.exercise3.gtl1.client.GuessGameClient localhost 8111
New guessing game. Range is 1..100. Time limit is 20.0s
Enter guess: 50
Turn 1: 50 was LOW, 17.5s remaining
Enter guess: 75
Turn 2: 75 was LOW, 14.6s remaining
Enter guess: 87
Turn 3: 87 was HIGH, 11.5s remaining
Enter guess: 81
Turn 4: 81 was HIGH, 8.4s remaining
Enter guess: 78
Turn 5: 78 was LOW, 5.8s remaining
Enter guess: 79
Turn 6: 79 was LOW, 3.1s remaining
Enter guess: 80
Turn 7: target was 80 - WIN
$ java CO2017.exercise3.gtl1.client.GuessGameClient localhost 8111
New guessing game. Range is 1..100. Time limit is 20.0s
Enter guess: abc
ERROR: Turn 0: 17.9s remaining
Enter guess: -10
ERROR: Turn 0: 15.3s remaining
Enter guess: 5
Turn 1: 5 was LOW, 11.7s remaining
Enter guess: 101
ERROR: Turn 1: 8.1s remaining
Enter guess: lemons
ERROR: Turn 1: 2.5s remaining
Enter guess:
Turn 1: target was 35 - LOSE
 
 
 
 
 
Test server
 
One of the key requirements of this exercise is that yourserver and client are able to interoperate with any otherversion that correctly implement the protocol. 
 
To assist you with this, there are some test version of theGuessing Game Server up and running that you can try outwith your own client. 
 
The test servers are running the phase 3 version of theserver, but phase 1 and phase 2 versions of the clientshould still work with it. Note that when the time is up,the server will close the connection. 
 
The test servers are running on host xanthus.mcscw3.le.ac.uk on ports 2017, 2117,2217 and 2317. Each server should be able to deal withmultiple simultaneous connections. In addition, theservers will automatically re-start every 2 hours. 
 
The host xanthus will only accept connections fromon-campus (not includingwifi/eduroam). Therefore, if youwant to use the test service, you will need to remotelogin and copy your compiled code onto xanthus (see below). 
 
Suppose your code is compiled into a jar file calledexercise3.jar. Then this is an example of how to connectto the server (replace abc123 with your ownusername): 
 
$ java -cp exercise3.jar CO2017.exercise3.abc123.client.GuessGameClient xanthus.mcscw3.le.ac.uk 2017
New guessing game. Range is 1..200. Time limit is 60.0s
Enter guess: 
 
Exporting your code to xanthus fortesting
 
This is not necessary is you are testingyour code "locally" (ie using one of the computersin the Informatics labs). 
 
If you are developing your code remotely (eg usingyour own laptop) and want to test your client with thetest server on xanthus, then you will need to export yourcode to xanthus. It should not matter if your aredeveloping on a Windows or Mac machine, because compiledjava code should work on any system. 
 
Most developments environments (eg eclipse) have anoption to export a java project as a "jar"file. Once you have done this you can transfer theresulting file to xanthus (using sftp or similar), andthen run it as shown above. 
 
 
Hints and advice
 
I/O streams
 
To avoid confusion, all data should be sent as String values. Do not use Data readers/writers to send numbers. Youshould use something very like this (on both ends of theconnection): 
 
  BufferedReader rdr = new
  BufferedReader(new InputStreamReader(server.getInputStream(),
                                       "UTF-8"));
  PrintWriter out = new PrintWriter(server.getOutputStream(),true);
 
As long as you remember the extra "true"parameter to the PrintWriter constructor, itwill auto-flush the stream whenever you use println, printf or format to send output. 
 
You can then use readLine to read incomplete lines on the other end of the connection. 
 
Processing protocol messages from the server
 
All of the protocol messages from the server are stringsof the form: WORD:nn:nn. In other words, acolon separated string consisting of a short word, andthen 2 integer numbers. Note that in some cases one of theinteger numbers should be treated as a longvalue. 
 
You can use a Scanner from the java.util package to process such strings. 
 
You can see an example of a Scanner in use inthis data reader demo program. 
 
Random number for thetarget
 
Your GameState class needs to generate a newrandom target number in the range for each new game. Thiscan be done using the java.util.Randomclass. You need to create an instance of the Random class as a static attribute: 
 
 private static final Random RANDGEN = new Random(); 
 
You can then use the nextInt method in the GameState constructor to get arandom number in the right range, for example: 
 
 target = RANDGEN.nextInt(max)+1 
 
Unique character identifier for eachclient
 
From phase 2 onwards, on the server side each newconnection should be given its own unique characteridentifier. 
 
Since each new client connection gets its own GuessGameServerHandler instance in phase 2,the simplest approach to giving each new connection itsown character identifier, is to have a class(static) attribute that records the next character to be allocated. Theconstructor can then use the value to set this instanceattribute, and increment the class attribute so that it isready for the next instance. 
 
Timing in java
 
In phase 3, you need to enforce the time limits of theguessing game. Correctly handling all aspects of timing isnotoriously complicated, and is beyond the scope of thismodule. Instead you should follow these simple guidelines. 
Computer timeTimes (and dates) are represented as the number ofelapsed (milli)-seconds since the "epoch" (which isdefined as midnight on 1stJanuary 1970 in the Javalanguage spec). However, for this exercise,you are only interested in "relative" time; for examplethe difference between "now" and "10 seconds time". Use milliseconds to store and manipulate times internallyThe specification mostly describes the behaviour interms of milliseconds. Your code should store, transmitand compare times using milliseconds values. Note that youshould use a long type to store a millisecondvalue.Use seconds when interacting with the userWhen the server is invoked the time limit is presentedin whole seconds. Similarly when the client responds tothe user, it should present the time remaining in seconds(to 1 decimal place accuracy).Getting the timeJava has a number of methods for finding the currenttime. You should use the expression 
System.currentTimeMillis()
to get the current time (in milliseconds). 
Interrupting console input
 
In phase 3 you need to allow for the possibility that thegame ends while the client is waiting for the user toenter a number. The normal System.in.readLine() method is notinterruptable, which would mean your clientprogram cannot properly terminate until the user enterssomething (even though they have already lost the game). 
 
The simplest solution is to use an enhanced readLine method that checks the status of theunderlying stream, as in this example code: 
 
  public String readLineTimeout(BufferedReader reader,
                                long timeout)
    throws TimeoutException, IOException {
    long starttime = System.currentTimeMillis();
 
    while (!reader.ready()) {
      if (System.currentTimeMillis() - starttime >= timeout)
        throw new TimeoutException();
 
      // short delay between polling the buffer
      try { Thread.sleep(50); } catch (Exception ignore) {}
    }
 
    return reader.readLine(); // won't block since reader is ready
  }
 
 
Assessment and submission
 
Overall: 15% of MODULE mark
 
 
Submission andassessment
 
Your work will be marked anonymously by systematicallyreplacing your username in your submitted files (and thenreversing the process when all marking is complete). Yourwork cannot be totally anonymous if you include yourreal name in the submitted files. 
 
Your complete solution should be in the specified sourcefiles. It is acceptable to use additional local classes within the source files specified. 
 
PLEASE check back here prior to submitting your work incase there are any last minute updates. 
 
Static evaluation
 
Your work will be assessed on both functionality (withdynamic testing using various input parameters, see below), andstatically on matters of layout and coding style including,but not limited to: 
•Use of comments, including clear identification ofthe author (by username).
•Appropriate choice of identifier names (variables, etc).
•Indentation, layout and spacing of code.
•Where class, method and attribute names are specified,you should stick precisely to thespecification.
•Where output strings are specified, you should conformto the specification. Generally you should not include output that is not explicitlyrequired.
 
Dynamic testing
 
Your code will be tested using a linux environment verysimilar to that on the linux machines in the CS departmentlabs.
NB: your code should compile successfullywith simple invocations like this "javacCO2017/exercise3//server/.java" (etc)at the command line. 
 
It is important that your classes provide the specifiedinterfaces exactly as described as each class will be testedin isolation, or against the "reference" implementation (inother words against the model answer). 
 
Assessment
 
Outline of the marking scheme
Phase 1Roughly 70% of the marks available for getting aworking client and single threaded server; divided into30% for the client and 40% for the server.Phase 2Roughly 15% for extending the server so that it canhandle multiple concurrent clients.Phase 3Roughly 15% for extending the server so that itcorrectly handles game over due to "time-up" condition.  •Contents:
•Module evaluation time!
•Preamble
•Question 1 — Number SquareService
•Client
•Server
•Extra features
•Question 2 — Number Guessing Game
 
    
 
联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!