Server Sockets

download Server Sockets

of 20

description

server sockets

Transcript of Server Sockets

  • Server Sockets

    AR Tawil

    Network Programming

  • 2A server provides a network service of some kind

    A server must be running before we try using a client to connect to it.

    The server listens for connections on its own socket.

    When a connection is made, the server sets up a new socket for communication with the client and goes back to listening on the original socket.

    NOTE: Multiple threads are required to allow the communication and the listening to occur simultaneously

    What is a server?

  • The class java.net.ServerSocket implements server sockets.

    The ServerSocket class

    3

    ServerSocket

    Object

    ServerSocket(port : int)

    ServerSocket(port : int, backlog : int)

    process

    + accept() : Socket

    + close()

    + getInetAddress()

    + getLocalPort()

    + setSoTimeout(timeout : int)

    A server socket:

    Waits for requests to come in over the network. Performs some operation based on that request Possibly returns a result to the requester.

    Here is the class diagram for ServerSocket:

  • There are three constructors for ServerSocket, each requires a port.

    By default, the backlog of waiting requests is 50.

    Creating a new ServerSocket

    4

    Providing a port number of 0 means that any free port should be used. The getLocalPort() method is used to find out which port number was used.

  • The two main methods of a ServerSocket are accept() and close().

    The accept() method listens for a connection to be made to this ServerSocket and accepts it. A new Socket is created and returned.

    The accept() method blocks until a connection is made. To block means

    that the method does not return until a client has connected. The setSoTimeout method is used to limit the length of time that accept will

    block. The default is to block forever.

    The close() method closes the ServerSocket.

    Using a ServerSocket

    5

  • An example ServerSocket

    6

    Here is an example of the creation of a ServerSocket:

    int port = 9999;

    ServerSocket serverSocket = new ServerSocket(port);

    Socket clientConnection = serverSocket.accept();

    Just as when we create any kind of Socket, the above operations can generate an IOException, so should be enclosed in a try/catch

    clause.

    After use, both the clientConnection and serverSocket must

    be closed. We should do that in a finally clause.

  • The constructor for ServerSocket will generate an IOException if a

    server already exists on the specified port.

    The exception is actually a java.net.BindException.

    Problems creating a ServerSocket

    7

  • A local port scanner

    8

    We can write a program to scan ports on the local machine to search for existing servers.

    Here is the code for our local port scanner.

    public class LocalPortScanner {

    public static void main(String[] args) {

    for (int port = 1; port < 65535; port++) {try {

    ServerSocket serverSocket = new ServerSocket(port);

    try {serverSocket.close();

    } catch(IOException e) {}} catch (BindException e) {

    System.out.println(e +

    "\r\nThere is already a server on port " +port);

    }

    }}

    }

    The outer catch will catch exceptions from the ServerSocket constructor.

    We need a try/catch when we close the ServerSocket because close operations can also generate an IOException.

  • Our first server will wait for a single connection and respond to that connection by sending astring to the client.

    We will not write a client program for this server. We can use telnet to connect to it.

    Here is an outline of the code necessary for our server...

    1. Create a new server socketServerSocket serverSocket = new ServerSocket(port);

    2. Accept connections on the server socket and get a new socketSocket clientConnection = serverSocket.accept();

    3. Get the output stream from clientConnectionOutputStreamWriter out =

    new OutputStreamWriter(clientConnection.getOutputStream());

    4. Write some output to the clientout.write("some text\r\n");

    The above code must be in a try/catch in order to catch IOExceptions

    There must be a finally clause in which we close both serverSocket and clientConnection.

    A simple server

    9

  • The classes we need to import to compile our server are:

    import java.net.ServerSocket;

    import java.net.Socket;

    import java.io.OutputStreamWriter;

    import java.io.IOException;

    Imports for our server

    10

  • Here is the full code for our server:public class HelloServer {

    public static void startService(int port) {

    try {

    System.out.println("Starting hello server port " + port);

    ServerSocket serverSocket = new ServerSocket(port);

    System.out.println("Waiting...");

    Socket clientConnection = serverSocket.accept();

    System.out.println("Accepted from " +

    clientConnection.getInetAddress());

    OutputStreamWriter out =

    new OutputStreamWriter(clientConnection.getOutputStream());

    out.write("Hello, you have connected. Bye Bye!\r\n");

    out.flush(); // necessary

    } catch (IOException e) {

    System.out.println(e);

    } finally {

    System.out.println("Hello Server closing down");

    // close clientConnection and serverSocket

    // code omitted, see next slide

    }

    }

    The code for our server

    11

    public static void main(String[] args) {

    if (args.length != 1) {

    throw new IllegalArgumentException("Usage: HelloServer ");

    } else {

    startService(Integer.parseInt(args[0]));

    } } }

  • The finally clause on the previous slide contains the following code:

    finally {

    System.out.println("Hello Server closing down");

    try {

    if (clientConnection != null) {

    clientConnection.close();

    }

    } catch (IOException e) {}

    try {

    if (serverSocket != null) {

    serverSocket.close();

    }

    } catch (IOException e) {}

    }

    We need to close the ServerSocket and the clientConnection socket safefully.

    An IOException can be thrown when closing a Socket or a ServerSocket.

    We dont need to close the OutputStream because closing the Socket will do that for us.

    Closing the sockets

    12

  • Testing a server involves running two programs in different windows.

    We need to run the server.

    We need to run a client program that will connect to the server.

    Testing a server

    13

  • Here is the code for a simple Daytime server

    public static void startService(int port) {

    ServerSocket serverSocket = null;

    Socket clientConnection = null;

    try {

    serverSocket = new ServerSocket(port);

    clientConnection = serverSocket.accept();

    OutputStream out = clientConnection.getOutputStream();

    SimpleDateFormat formatter =

    new SimpleDateFormat ("EEE MMM d H:mm:ss yyyy");

    String dateString = formatter.format(new Date());

    out.write(dateString.getBytes());

    out.write(\n);

    out.flush();

    } catch (IOException e) {

    System.out.println(e);

    } finally {

    System.out.println("Closing down");

    // close serverSocket and clientConnection

    // ...

    }

    }

    Implementing a Daytime Server

    14

  • Our server will exit after one client has connected. The above code implements the following steps.

    We create a ServerSocket and use it to call accept() and wait for a connection.

    After getting a connection we get the OutputStream of the Socket connecting to the

    client.

    We format the current time of day according to the Daytime Protocol. We use java.util.Date to get the current date and java.text.SimpleDateFormat to

    format the date.

    We write the string to the OutputStream, followed by a carriage return and line

    feed. We then flush the output stream.

    Any IOExceptions are caught.

    Finally we close the sockets and exit.

    15

  • Another client that we implemented was the Echo client

    An echo server accepts connections and echoes any input that it receives back to the client.

    An echo server requires both input and output. The daytime server only required output.

    Echo servers usually occupy port 7.

    An Echo Server

    16

  • Here is our code for an Echo Server:

    public static void startService(int port) {

    try {

    ServerSocket serverSocket = new ServerSocket(port);

    Socket clientConnection = serverSocket.accept();

    BufferedReader in =

    new BufferedReader(

    new InputStreamReader(

    clientConnection.getInputStream()));

    OutputStream out = clientConnection.getOutputStream();

    String line = in.readLine();

    while (line != null) {

    out.write(line.getBytes());

    out.write(\n);

    out.flush();

    line = in.readLine();

    }

    } catch (IOException e) {

    System.out.println(e);

    } finally {

    System.out.println("Echo Server closing down");

    // close serverSocket and clientConnection

    // code as for Daytime Server ...

    }

    }

    Implementing an Echo Server

    17

    serverSocket

    clientConnection

    A Client

    Requestconnection

    in

    out

  • The code is very similar to that of the Daytime server.

    Our server will exit after one client has connected. The above code implements the following steps.

    We create a ServerSocket and use it to call accept() and wait for a connection.

    After getting a connection we get the InputStream of the Socket connecting to the client andwrap that in an InputStreamReader and then a BufferedReader.

    Next we get the OutputStream of the Socket connecting to the client.

    We read the first line of input using BufferedReader.readLine().

    The main operation of the server is in a simple while loop:

    The loop will exit when readLine() returns null (meaning the input stream has closed). That can happen when the user types EOF, CTRL-D (unix) or CTRL-Z (pc), into the client program.

    We write the input line to the OutputStream with a following carriage return and newline.

    We flush() the OutputStream to ensure the output is sent.

    Finally we read the next line of input, again using BufferedReader.readLine().

    Any IOExceptions are caught.

    Finally we close the sockets and exit.

    18

  • The servers we have seen so far service a single client and then exit.

    Our first attempt to handle more than one client is to put the accept() code into a loop.

    Here is the modification to the EchoServer to allow it continue servicing clients:

    serverSocket = new ServerSocket(port);

    while (true) {clientConnection = serverSocket.accept();

    BufferedReader in = ...

    OutputStream out = ...

    String line = in.readLine();

    while (line != null) {

    out.write(line.getBytes());

    out.write(\n);

    out.flush();

    line = in.readLine();

    }

    try {

    if (clientConnection != null) {

    clientConnection.close();

    }

    } catch (IOException e) {}

    }

    Handling multiple clients

    19

    Notice that we have to close the clientConnection after servicing each client.

    serverSocket

    clientConnection

    A Client

    Requestconnection

    in

    out

  • When running our EchoServer we come up against a problem. While the server is servicingone client it cannot service any other clients

    Other clients attempting to connect to the server before the current client has disconnectedwill have to wait.

    Such behaviour is not convenient. A client could occupy the server for an undefined period oftime.

    We will leave the solution to that problem until the next lecture.

    What happens when two clients connect simultaneously?

    20