开发者

Shifting from blocking to non-blocking I/O with javanio

开发者 https://www.devze.com 2023-02-20 11:58 出处:网络
i adapt this code How to send and receive serialized object in socket channel my real time simulation to send objects but i am running into exceptions one after another is it because this code blockin

i adapt this code How to send and receive serialized object in socket channel my real time simulation to send objects but i am running into exceptions one after another is it because this code blocking in nature how this code can be converted in to non blocking with javanio

  /*
     * Writer
     */
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.net.InetSocketAddress;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;

    public class CleanSender implements Runnable {

        private SimManager SM;
        private BallState ballState = new BallState(10, 5);
        private ServerSocketChannel ssChannel;

        private Thread tRunSer = new Thread(this, "ServerSelectThread");

    public static void main(String[] args) throws IOException {

        CleanSender server = new CleanSender();
        server.startServer();

    }

    private void startServer() throws IOException {
        ssChannel = ServerSocketChannel.open();
        ssChannel.configureBlocking(true);
        int port = 2345;
        ssChannel.socket().bind(new InetSocketAddress(port));
        // SM = new SimManager(this, BS);
        // SM.start(); // GameEngine thread starting here
        tRunSer.start();
    }

    public void run() {
        try {
            SocketChannel sChannel = ssChannel.accept();

            while (true) {

                ObjectOutputStream oos = new ObjectOutputStream(sChannel
                        .socket().getOutputStream());
                oos.writeObject(ballState);
                System.out.println("Sending String is: '" + ballState.X + "'" + ballState.Y);
                oos.close();
                System.out.println("Sender Start");
                System.out.println("Connection ended");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client: which is continously looking for reply from server

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

public class CleanReceiver implements Runnable {

    private SocketChannel sChannel;
    private Thread receiverThread = new Thread(this, "receiverThread");


    private synchronized  void startServer() throws IOException {
         sChannel = SocketChannel.open();
         sChannel.configureBlocking(true);
         if (sChannel.connect(new InetSocketAddress("localhost", 2345))) {
             receiverThread.start();
         }
    }
public void run() {

    while (true) {
        try {
            ObjectInputStream ois = new ObjectInputStream(sChannel.socket()
                    .getInputStream());

            BallState s = (BallState) ois.readObjec开发者_开发技巧t();
            System.out.println("String is: '" + s.X + "'" + s.Y);
            ois.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("End Receiver");
    }
}


      public static void main(String[] args) 
        throws IOException, ClassNotFoundException {

            CleanReceiver rc=new CleanReceiver();
            rc.startServer();

            System.out.println("End Receiver");
        }
}

Will this design work in the scenario when server has to keep connect the client and simultaneous send the simulation state to already connected client?, i m looking for experts glance.

thanks,

jibbylala


If you are using ObjectInputStream or ObjectOutputStream I suggest you stick with blocking IO. Using non-blocking IO with these libraries is 10x harder for no real benifit.

Have you considered using ServerSocket and Socket instead of NIO. These will be easier to use and what the object streams were originall designed to use,


Your code have two main problems:

  • You close streams after handling every single object, that causes closing of the associated sockets, so they are no longer valid and cannot be used for processing the following objects. At the receiving side you don't need close() inside a loop at all, at the sending side use flush() instead of close() to ensure that buffers are flushed.

  • When implementing blocking IO you (usually) need to start a new thread on the server for each client. It would allow you to communicate with multiple clients simultaneously. Beware of thread synchronization problems in this case!

If having a thread per client is not acceptable for you, you can implement server in a non-blocking way, but, as already said by Peter Lawrey, it's more complex, so I suggest you to get it working with blocking IO first.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号