Practical session 11
Download
1 / 22

Practical Session 11 - PowerPoint PPT Presentation


  • 85 Views
  • Uploaded on

Practical Session 11. Multi Client-Server Java NIO. Supporting Multiple Clients. The basic flow of logic in such a server is this: while (true) { accept a connection; create a thread to deal with the client; }

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Practical Session 11' - ansel


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Practical session 11

Practical Session 11

Multi Client-Server

Java NIO


Supporting multiple clients
Supporting Multiple Clients

  • The basic flow of logic in such a server is this:

    while (true) {

    accept a connection;

    create a thread to deal with the client;

    }

  • The thread reads from and writes to the client connection as necessary.


The server interface
The Server Interface

  • interface ServerProtocol:

    • String processMessage(String msg);          

    • booleanisEnd(String msg);

  • In order to organize the work of the Server, and to allow several protocols, we create an interface:

    • processMessage: a function that decides what to do with the content received.

    • isEnd: returns true if the message equals our ‘exit’ command.


Connectionhandler
ConnectionHandler

  • In order to allow more than one client to connect to our server, we need to run each connection in its own thread.

  • ConnectionHandler is a Runnable that handles one connection.

  • Each client that wishes to connect to our server initiates the connection.

  • The server accepts the connection from the client.

  • The socket returned is sent to the ConnectionHandler object.

  • ConnectionHandler is run as a Thread.

  • Server goes back to blocking mode, waiting for a new connection.


Multiclient server implementation
MultiClient – Server Implementation

  • ServerProtocol  [Interface]

    • processMessage

    • isEnd

  • EchoProtocol implements ServerProtocol

    • processMessage: message received is returned

    • isEnd: returns true if message is ‘bye’

  • ConnectionHandler[Runnable]

    • Receives messages from client [msg = in.readLine()]

    • Processes message [using process()] using EchoProtocol

      • If message is ‘bye’, exits thread [protocol.isEnd(msg)]

      • Else, message is sent back to client [out.println(response)]

    • Sends returned result from processing to client.

  • MultipleClientProtocolServer [Runnable]

    • Our server – runs as a thread

    • Creates ServerSocket, listens to a port

    • Runs ConnectionHandler in a thread once accept() returns a socket.

http://www.cs.bgu.ac.il/~spl141/PracticalSession11/MultipleClientProtocolServer


Java non blocking io
Java Non-blocking IO

  • In our examples, the server gets stuck on

    • msg = in.readLine()

    • clientSocket = serverSocket.accept()

    • out.println(msg) //writing faster than the other side can read

  • You cannot do something else while these methods are blocking. (process client messages, handle other clients etc.).


Java non blocking io1
Java Non-blocking IO

  • Solution? java.nio.

  • The package is an efficient InputOutput package, which supports Non-blocking IO.

  • NIO Concepts:

    • Channels

    • Buffers

    • Selectors

  • Tutorial: http://tutorials.jenkov.com/java-nio/index.html


Channels our sockets
Channels [our sockets]

  • An Object you can read from and write to.

  • Channels can be either blocking (by default) or non-blocking.

  • SocketChannel:

    • http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html

    • Same as regular Socket object.

    • Difference: read(), write() can be non-blocking.

  • ServerSocketChannel:

    • http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/ServerSocketChannel.html

    • accept() returns SocketChannel

    • Same as regular ServerSocket object.

    • Difference: accept() can be non-blocking.

  • Does not block until a client connects.

  • Checks if a client is trying to connect, if so returns a new socket, otherwise returns null!


Setting up serversocketchannel and socketchannel
Setting up ServerSocketChannel and SocketChannel

  • ServerSocketChannel :

    • int port = 9999;

    • ServerSocketChannel ssChannel = ServerSocketChannel.open();

    • ssChannel.configureBlocking(false);

    • ssChannel.socket().bind(new InetSocketAddress(port));

  • SocketChannel:

    • SocketChannel sChannel=SocketChannel.open();

    • sChannel.connect(new InetSocketAddress("host/ip", 9999));

    • sChannel.configureBlocking(false);

http://docs.oracle.com/javase/1.4.2/docs/api/java/net/InetSocketAddress.html


Buffers our containers
Buffers [our containers]

  • The objects which hold the data to be sent and data received.

  • Channels know how to read and write into Buffers, and buffers can read and write into other buffers.

  • Java NIO comes with the following Buffer types:

    • ByteBuffer

    • CharBuffer

    • DoubleBuffer

    • FloatBuffer

    • IntBuffer

    • LongBuffer

    • ShortBuffer

http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html


Creating buffers
Creating Buffers

  • We'll be using ByteBuffer.

  • These are buffers that hold bytes.

  • Creating a new ByteBuffer: [Method I]

    • final int NUM_OF_BYTES = 1024;

    • ByteBuffer buffer = ByteBuffer.allocate(NUM_OF_BYTES);

  • Creating a new ByteBuffer: [Method II]

    • String message = “Sentence to write into buffer”;

    • ByteBuffer buffer = ByteBuffer.wrap(message.getBytes(),”UTF-8”);


Buffer markers
Buffer Markers

  • Each buffer has capacity, limit, and position markers.

  • Capacity:

    • Being a memory block, a Buffer has a certain fixed size, also called its "capacity".

    • You can only write capacity bytes, longs, chars etc. into the Buffer.

    • Once the Buffer is full, you need to empty it (read the data, or clear it) before you can write more data into it.

  • Position:

    • Writing data to buffer:

      • Initially the position is 0.

      • When a byte, long etc. has been written into the Buffer the position is advanced to point to the next cell in the buffer to insert data into.

      • Position can maximally become capacity - 1.

    • Reading data from buffer:

      • When you flip a Buffer from writing mode to reading mode, the position is reset to 0.

      • As you read data from the Buffer you do so from position, and position is advanced to next position to read.

  • Limit:

    • In write mode:

      • The limit of a Buffer is the limit of how much data you can write into the buffer.

      • The limit is equal to the capacity of the Buffer.

    • When flipping the Buffer into read mode:

      • The limit means the limit of how much data you can read from the buffer.

      • When flipping a Buffer into read mode, limit is set to write position of the write mode.

      • In other words, you can read as many bytes as were written (limit is set to the number of bytes written, which is marked by position).





Buffer flipping
Buffer Flipping

  • The flip() method switches a Buffer from writing mode to reading mode.

  • Calling flip() sets the position back to 0, and sets the limit to where position just was.

  • The position marker now marks the reading position, and limit marks how many bytes were written into the buffer - the limit of how many bytes, chars etc. that can be read.

  • Example:

    • You create a ByteBuffer.

    • Write data into the buffer.

    • Flip()

    • Send the buffer to the channel.


Buffer io operations
Buffer IO Operations

  • Readingfrom a channel to a buffer:

    numBytesRead = socketChannel.read(buf);

    • Contents found in socketChannel are read from their internal container object to our buffer.

  • Writingfrom a buffer to a channel:

    numBytesWritten = socketChannel.write(buf);

    • Contents from our buf object are written to the socketChannel’s internal container to be sent.

  • If read or write returns -1, it means that the channel is closed.

  • Read and write operations on Buffers update the position marker accordingly.


More bytebuffer methods
More ByteBuffer Methods

  • clear():

    • Makes a buffer ready for a new sequence of channel-read or relative put operations.

    • Sets the limit to the capacity .

    • Sets the position to zero.

  • rewind():

    • Makes a buffer ready for re-reading the data that it already contains.

    • Leaves the limit unchanged.

    • Sets the position to zero.


Stringmessagetokenizer interface
StringMessageTokenizer Interface

  • void addBytes(ByteBuffer bytes);

    • Receives a Buffer of bytes containing data to be converted to chars.

  • booleanhasMessage();

    • Is there a complete message ready?

  • String nextMessage();

    • Get the next complete message if it exists, advancing the tokenizer to the next message.


  • Fixedseparatormessagetokenizer
    FixedSeparatorMessageTokenizer

    • FixedSeparatorMessageTokenizer(String separator, Charset charset)

      • The constructor.

      • Between two messages in the buffer we have a separator.

      • Messages are encoded [chars to bytes] and decoded [bytes to chars] using the given charset [ASCII, UTF-8]

    • public synchronized void addBytes(ByteBuffer bytes):

      • Array of bytes received is converted to string and concatenated to the ones before it.

    • public synchronized booleanhasMessage():

      • Checks if the buffer has a complete message, if so true, otherwise false. [done by checking if the separator exists in the string array]

    • public synchronized String nextMessage()

      • Returns the next complete message in the buffer.


    Nio echo client
    NIO Echo Client

    • http://www.cs.bgu.ac.il/~spl141/PracticalSession10/NIOEchoClient


    C echo client
    C++ Echo Client

    • Connect a socket to a host and port:

      boost::asio::ip::tcp::socket socket_;

      boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(host_), port_);

      boost::system::error_code error;

      socket_.connect(endpoint, error);

    • Read from socket:

      boost::asio::buffer(startingPointPointer, SizeToReadInBytes, exception) //exception is optional

      //tmp holds the number of bytes read so far; bytes: an array of chars to read the received bytes from

      socket_.read_some(boost::asio::buffer(bytes+tmp, bytesToRead-tmp), error)

    • Write to socket:

      socket_.write_some(boost::asio::buffer(bytes + tmp, bytesToWrite - tmp), error)

    • Example:

      • 05_Boost_Echo_Client


    ad