【问题标题】:Shifting from blocking to non-blocking I/O with javanio使用 javanio 从阻塞转换为非阻塞 I/O
【发布时间】:2011-03-28 13:33:41
【问题描述】:

我修改了这个代码How to send and receive serialized object in socket channel我的实时模拟来发送对象,但是我一个接一个地遇到异常,是因为这个代码本质上是阻塞的,如何用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();
        }
    }
}

客户端:一直在寻找服务器的回复

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.readObject();
            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");
        }
}

这种设计在服务器必须保持连接客户端并同时将模拟状态发送到已经连接的客户端的场景中是否有效?,我正在寻找专家的眼光。

谢谢,

吉比拉拉

【问题讨论】:

    标签: java sockets stream io nio


    【解决方案1】:

    如果您使用 ObjectInputStream 或 ObjectOutputStream,我建议您坚持阻塞 IO。对这些库使用非阻塞 IO 的难度是 10 倍,但没有真正的好处。

    您是否考虑过使用ServerSocketSocket 来代替NIO。这些将更易于使用,并且对象流的最初设计用途是什么,

    【讨论】:

    • 我认为我遇到的问题是由于阻塞性质还是?
    【解决方案2】:

    您的代码有两个主要问题:

    • 在处理完每个对象后关闭流,这会导致关联的套接字关闭,因此它们不再有效并且不能用于处理以下对象。在接收端,您根本不需要在循环中使用close(),在发送端使用flush() 而不是close() 以确保刷新缓冲区。

    • 在实现阻塞 IO 时,您(通常)需要在服务器上为每个客户端启动一个新线程。它将允许您同时与多个客户端进行通信。小心这种情况下的线程同步问题!

    如果您不能接受每个客户端有一个线程,您可以以非阻塞方式实现服务器,但是正如 Peter Lawrey 已经说过的,它更复杂,所以我建议您让它与阻塞 IO 一起工作首先。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-06
      • 2020-05-24
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      相关资源
      最近更新 更多