Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
maxg committed Oct 30, 2015
0 parents commit 47a7b1e
Show file tree
Hide file tree
Showing 7 changed files with 447 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
/bin
17 changes: 17 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ex22-square</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
98 changes: 98 additions & 0 deletions src/square/SquareClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package square;

import java.io.*;
import java.net.Socket;

/**
* SquareClient is a client that sends requests to the SquareServer
* and interprets its replies.
* A new SquareClient is "open" until the close() method is called,
* at which point it is "closed" and may not be used further.
*/
public class SquareClient {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
// Rep invariant: socket, in, out != null

/**
* Make a SquareClient and connect it to a server running on
* hostname at the specified port.
* @throws IOException if can't connect
*/
public SquareClient(String hostname, int port) throws IOException {
socket = new Socket(hostname, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
}

/**
* Send a request to the server. Requires this is "open".
* @param x number to square
* @throws IOException if network or server failure
*/
public void sendRequest(int x) throws IOException {
out.print(x + "\n");
out.flush(); // important! make sure x actually gets sent
}

/**
* Get a reply from the next request that was submitted.
* Requires this is "open".
* @return square of requested number
* @throws IOException if network or server failure
*/
public int getReply() throws IOException {
String reply = in.readLine();
if (reply == null) {
throw new IOException("connection terminated unexpectedly");
}

try {
return Integer.valueOf(reply);
} catch (NumberFormatException nfe) {
throw new IOException("misformatted reply: " + reply);
}
}

/**
* Closes the client's connection to the server.
* This client is now "closed". Requires this is "open".
* @throws IOException if close fails
*/
public void close() throws IOException {
in.close();
out.close();
socket.close();
}




private static final int N = 100;

/**
* Use a SquareServer to square all the integers from 1 to N.
*/
public static void main(String[] args) {
try {
SquareClient client = new SquareClient("localhost", SquareServer.SQUARE_PORT);

// send the requests to square 1...N
for (int x = 1; x <= N; ++x) {
client.sendRequest(x);
System.out.println(x + "^2 = ?");
}

// collect the replies
for (int x = 1; x <= N; ++x) {
int y = client.getReply();
System.out.println(x + "^2 = " + y);
}

client.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
97 changes: 97 additions & 0 deletions src/square/SquareQueue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package square;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
* Squares integers.
*/
class Squarer {

private final BlockingQueue<Integer> in;
private final BlockingQueue<SquareResult> out;
// Rep invariant: in, out != null

/**
* Make a squarer that will listen for requests and generate replies.
* @param requests queue to receive requests from
* @param replies queue to send replies to
*/
public Squarer(BlockingQueue<Integer> requests, BlockingQueue<SquareResult> replies) {
this.in = requests;
this.out = replies;
}

/**
* Start handling squaring requests.
*/
public void start() {
new Thread(new Runnable() {
public void run() {
while (true) {
// TODO: we may want a way to stop the thread
try {
// block until a request arrives
int x = in.take();
// compute the answer and send it back
int y = x * x;
out.put(new SquareResult(x, y));
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
}
}

/**
* An immutable squaring result message.
*/
class SquareResult {
private final int input;
private final int output;

/**
* Make a new result message.
* @param input input number
* @param output square of input
*/
public SquareResult(int input, int output) {
this.input = input;
this.output = output;
}

// TODO: we will want more observers, but for now...

@Override public String toString() {
return input + "^2 = " + output;
}
}

public class SquareQueue {

/**
* Create and use a squarer.
*/
public static void main(String[] args) {

BlockingQueue<Integer> requests = new LinkedBlockingQueue<>();
BlockingQueue<SquareResult> replies = new LinkedBlockingQueue<>();

Squarer squarer = new Squarer(requests, replies);
squarer.start();

try {
// make a request
requests.put(42);

// maybe do something concurrently...

// read the reply
System.out.println(replies.take());
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
104 changes: 104 additions & 0 deletions src/square/SquareServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package square;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
* SquareServer is a server that squares integers passed to it.
* It accepts requests of the form:
* Request ::= Number "\n"
* Number ::= [0-9]+
* and for each request, returns a reply of the form:
* Reply ::= (Number | "err") "\n"
* where a Number is the square of the request number,
* or "err" is used to indicate a misformatted request.
* SquareServer can handle only one client at a time.
*/
public class SquareServer {
/** Default port number where the server listens for connections. */
public static final int SQUARE_PORT = 4949;

private ServerSocket serverSocket;
// Rep invariant: serverSocket != null

/**
* Make a SquareServer that listens for connections on port.
* @param port port number, requires 0 <= port <= 65535
*/
public SquareServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
}

/**
* Run the server, listening for connections and handling them.
* @throws IOException if the main server socket is broken
*/
public void serve() throws IOException {
while (true) {
// block until a client connects
Socket socket = serverSocket.accept();
try {
handle(socket);
} catch (IOException ioe) {
ioe.printStackTrace(); // but don't terminate serve()
} finally {
socket.close();
}
}
}

/**
* Handle one client connection. Returns when client disconnects.
* @param socket socket where client is connected
* @throws IOException if connection encounters an error
*/
private void handle(Socket socket) throws IOException {
System.err.println("client connected");

// get the socket's input stream, and wrap converters around it
// that convert it from a byte stream to a character stream,
// and that buffer it so that we can read a line at a time
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

// similarly, wrap character=>bytestream converter around the
// socket output stream, and wrap a PrintWriter around that so
// that we have more convenient ways to write Java primitive
// types to it.
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

try {
// each request is a single line containing a number
for (String line = in.readLine(); line != null; line = in.readLine()) {
System.err.println("request: " + line);
try {
int x = Integer.valueOf(line);
// compute answer and send back to client
int y = x * x;
System.err.println("reply: " + y);
out.print(y + "\n");
} catch (NumberFormatException e) {
// complain about ill-formatted request
System.err.println("reply: err");
out.println("err");
}
// important! flush our buffer so the reply is sent
out.flush();
}
} finally {
out.close();
in.close();
}
}

/**
* Start a SquareServer running on the default port.
*/
public static void main(String[] args) {
try {
SquareServer server = new SquareServer(SQUARE_PORT);
server.serve();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Loading

0 comments on commit 47a7b1e

Please sign in to comment.