java - 使用 javanio 从阻塞 I/O 转变为非阻塞 I/O

标签 java sockets stream io nio

我改编此代码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");
        }
}

当服务器必须保持连接客户端并同时将模拟状态发送到已连接的客户端时,这种设计是否有效?,我正在寻找专家一目了然。

谢谢

吉比拉拉

最佳答案

如果您使用 ObjectInputStream 或 ObjectOutputStream,我建议您坚持使用阻塞 IO。在这些库中使用非阻塞 IO 的难度增加了 10 倍,而且没有任何实际好处。

您是否考虑过使用ServerSocketSocket来代替NIO。这些将更容易使用以及对象流最初设计的用途,

关于java - 使用 javanio 从阻塞 I/O 转变为非阻塞 I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5459750/

相关文章:

node.js - 页面刷新后保存 TCP 套接字(连接)状态

java - 创建客户端-服务器应用程序以回显用户发送的内容

c++ - 使用 C++ 在 char 数组最后一个索引中添加值

linux - 一段时间后 HTTP Live Stream 停止播放

c# - 如何使用 DotNetZip 即时提取 ZIP 文件?

java - UDP套接字处理

java - 获取 spring bean 的新实例

java - Kotlin JNA 将声明的字段名称设为空列表

java - 使用线程时如何安全关闭流

java - spring 4 mvc app - 应用程序级异常处理程序