Java NIO Server端不能向客户端发送消息?

发布于 2021-11-29 18:44:50 字数 6859 浏览 837 评论 1

写了个程序,NIOServer,两个 Client,一个传统的 Client 和 一个 NIO Client,传统的 Client 和 NIO Client 都可以向服务器发送消息,但是 NIOServer 向客户端返回消息,却只有 NIO Client 可以收到消息,传统的 Client 却不能通过 Sockt.getInputStream() 得到消息。百思不得其解,NIO 不都是监听本来的 socket 连接,有数据则通知 NIO 获取连接并获得数据,然而传统的 Socket 连接,不是一直监听本来的 socket 连接, 照理说,不是一旦有数据写入,就可以获取,但是传统的 client Socket 连接,却不能获得数据?百思不得其解,请高手指点。下面是我写的一个简单的代码。

NioServer

public class NioServer {  
	
    private Selector selector;  
  
    public void initServer( int port ) throws IOException {  
        
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        
        serverSocketChannel.configureBlocking(false);
        
        serverSocketChannel.socket().bind( new InetSocketAddress(port) );
        
        this.selector = Selector.open();
        
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  
        
    }  
  
    /** 
     * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理 
     * @throws IOException 
     */  
    public void listen() throws IOException {  
    	
        while (true) {  
            
            selector.select();  
            
            Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
            
            while (iterator.hasNext()) {  
            	
                SelectionKey key = (SelectionKey) iterator.next();  
                
                iterator.remove();
                
                if (key.isAcceptable()) {  
                
                	System.out.println("event is acceptable ~~");
                	
                	accept( key );
                	
                }
                
                if (key.isReadable()) {  
                	
                	System.out.println("event is readable ~~");
                	
                    read( key );  
                }
                
            }  
  
        }  
    }  
    
    public void accept(SelectionKey key) throws IOException{
    	
        ServerSocketChannel server = (ServerSocketChannel) key.channel();  
        
        SocketChannel channel = server.accept();  
        
        System.out.println("channel id:" + channel.hashCode() );
        
        channel.configureBlocking(false);
        
        channel.register( this.selector, SelectionKey.OP_READ );
        
    }
        
    public void read(SelectionKey key) throws IOException{  
        
        SocketChannel channel = (SocketChannel) key.channel();
        
        ByteBuffer buffer = ByteBuffer.allocate( 1024 );

        channel.read(buffer);
        
        byte[] data = buffer.array();  

        String msg = new String(data).trim();  
        
        System.out.println( "received from client:" + msg );
        
        // 写数据到客户端
        channel.write( ByteBuffer.wrap( "hi client, server received your message".getBytes() ) ); 
        
    }  
      
    /** 
     * 启动服务端测试 
     * @throws IOException  
     */  
    public static void main(String[] args) throws IOException {
    	
        NioServer server = new NioServer();
        
        server.initServer(5678);
        
        server.listen();
        
    }  
  
}
Client
public class Client {  
	
    public static void main(String[] args) throws Exception {  
        
    	Socket server = new Socket(InetAddress.getLocalHost(), 5678);  
    	
        BufferedReader in = new BufferedReader( new InputStreamReader( server.getInputStream() ) );  
        
        PrintWriter out = new PrintWriter(server.getOutputStream());
        
        while (true) {  
        	
            out.println( "hello, I'm Native Client ~ " );
            
            out.flush();
            
            System.out.println("read from server: " + in.readLine() );
            
        }
        
    }  
    
}
NioClient
public class NioClient {  
	
    private Selector selector;  
  
    public void initClient(String ip,int port) throws IOException {  
        
    	SocketChannel channel = SocketChannel.open();  

        channel.configureBlocking(false);  
        
        this.selector = Selector.open();  
          
        channel.connect( new InetSocketAddress(ip,port) );  
          
        channel.register( selector, SelectionKey.OP_CONNECT );  
    }  
  
    public void listen() throws IOException {  
    	
        while (true) {  
        	
            selector.select();  
            
            Iterator<SelectionKey> ite = this.selector.selectedKeys().iterator();
            
            while (ite.hasNext()) {  
            	
                SelectionKey key = (SelectionKey) ite.next();
                
                ite.remove();
                
                if (key.isConnectable()) {  
                	
                    connect(key);
                      
                } 
                
                if (key.isReadable()) {  
                	
                    read(key);
                
                }
                
                if (key.isWritable() ){
                	
                	write(key);
                     	
                }
  
            }  
  
        }  
    }  
    
    public void connect(SelectionKey key) throws IOException{
        
        SocketChannel channel = (SocketChannel) key.channel();

        if(channel.isConnectionPending()){  
            channel.finishConnect();  
        }  
        
        channel.configureBlocking(false);  
        
        channel.register( this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE );     
        
    }
    
    public void read(SelectionKey key) throws IOException{  
    	
        SocketChannel channel = (SocketChannel)key.channel();
        
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        
        channel.read(buffer);
        
        byte[] data = buffer.array();
        
        String message = new String(data);
        
        System.out.println("recevie message from server: " + message);
    
    }  
    
    public void write(SelectionKey key) throws IOException{
    	
        SocketChannel channel = (SocketChannel) key.channel();
        
        channel.write(ByteBuffer.wrap( "hello, I'm Nio Client ~ ".getBytes()));
        
        key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); 

    }
      
    public static void main(String[] args) throws IOException {
    	
        NioClient client = new NioClient();
        
        client.initClient("localhost", 5678);
        
        client.listen();
        
    }  
  
}

程序代码逻辑很简单,Client 和 NioClient 均向 NioServer 发送消息,NioServer 收到消息后,向客户端反馈消息,但是只有 NioClient 可以收到服务器的响应,Client 却不行。



如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深巷少女 2021-11-30 04:27:24

BufferedReader只有读到换行符号或者读满8kb返回空,你需要在你服务器发送的数据中加入换行符,想要平台通用的话,加上rn

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文