Java IO and NIO server & client communications small chestnuts

Benpian entry contains a small chestnuts and some think the problem

BIO

Package Penalty for com.demo.bio; 

Import java.io. * ;
 Import java.net.ServerSocket;
 Import java.net.Socket;
 Import java.util.Scanner; 

/ ** 
 * Problem: open multiple clients, only server transmitting a sufficient number of the message, the client will receive 
 * / 
public  class Server { 

    public  static  void main (String [] args) throws Exception {
         new new Server () the startServer ();. 
    } 

    public  void the startServer () throws IOException { 
        serverSocket the serverSocket = new new the serverSocket (9999 );

        while (true){
            Socket client = serverSocket.accept();
            System.err.println("Client:" + client.getInetAddress().getHostAddress());
            OutputStream out = client.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"), true);
            writer.println("Hello!We are already connected!say 'bye' to close");

            new Thread(new SocketReadThread(client)).start();
            new Thread(new SocketWriteThread(client)).start();
        }

    }
}

/**
 * 读线程
 */
class SocketReadThread implements Runnable{

    private Socket socket;

    public SocketReadThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream in = socket.getInputStream();
            Scanner scanner = new Scanner(in, "UTF-8");
            boolean bye = false;
            while (!bye && scanner.hasNextLine()){
                String line = scanner.nextLine();
                System.out.println("Client Msg[" + socket + "]:" + line);
                if(line.trim().equals("bye")){
                    bye = true;
                }
            }
            in.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

/**
 * 写线程
 */
class SocketWriteThread implements Runnable{

    private Socket socket;

    public SocketWriteThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            OutputStream out = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"), true);
            Scanner scanIn = new Scanner(System.in);
            while (true){
                String line = scanIn.nextLine();
                writer.println(line);
                if (socket.isClosed()){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

package com.demo.bio;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 9999);
        OutputStream out = socket.getOutputStream();
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"), true);

        new Thread(new SocketReceiveThread(socket)).start();
        Scanner scanIn = new Scanner(System.in);
        while (!socket.isClosed()){
            String line = scanIn.nextLine();
            writer.println(line);
            if(line.trim().equals("bye")){
                socket.close();
            }
        }
    }


}
class SocketReceiveThread implements Runnable{

    private Socket socket;

    public SocketReceiveThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream in = socket.getInputStream();
            Scanner scanner = new Scanner(in, "UTF-8");
            boolean bye = false;
            while (!bye && scanner.hasNextLine()){
                String line = scanner.nextLine();
                System.out.println("Server Msg:" + line);
                if(line.trim().equals("bye")){
                    bye = true;
                }
            }
            scanner.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

BIO is not that hard, synchronous blocking. Achieve above mainly servers and clients I sentence you, Bala Bala Bala

NIO

Example I want to implement a client-server communication, my first version

package com.demo.nio;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * Question: Start the server, the client does not start when blocked in selector.select (); until the client connection will go down. 
 * Client Start: Get message to the client, and read the display; then write the data to a client; module then proceeds to the write operation, the write blocking. 
 * This time, the client has passed the read operation, and not read data, also entered the write module, waiting to be written, blocking. This explains why the client can not receive the first message server. 
 * Write client: client input data, sent to the server, leaving the module writes into the next cycle, and then read into the module, a first message to the server to read and display. 
 * The server receives: At this point the server and the client does not receive the message, because the module also writes blocked, so I want to read data, it is necessary to send data to the client to leave the write module, go to the next round cycle. 
 * This explains: Why write data to be read first. 
 * / 
Public  class Server { 

    Private  Boolean isFirst = to true ;
     Private a ServerSocketChannel SSC = null ;
     Private Selector Selector = null ; 

    public Server(int port) throws IOException {
        ssc = ServerSocketChannel.open();
        selector = Selector.open();
        InetSocketAddress inetAddress = new InetSocketAddress(InetAddress.getLocalHost(), port);
        
        ssc.socket().bind(inetAddress);
        ssc.configureBlocking(false);
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        listener(selector);
    }
    
    private void listener(Selector selector) throws IOException{
        while(true) { 
            System.out.println ( "connection requests from clients ..." ); 
            the selector.select (); 
            System.out.println ( "capture client connections ..." ); 
            the Set <the SelectionKey> = the selectedKeys Selector. the selectedKeys (); 
            the Iterator <the SelectionKey> Iterator = selectedKeys.iterator (); 

            the while (iterator.hasNext ()) { 
                the SelectionKey Key = Iterator.next ();
                 // connection event 
                IF (key.isAcceptable ()) { 
                    a ServerSocketChannel Channel =  (ServerSocketChannel) key.channel ();
                    channel.accept (). the configureBlocking ( false) .register (Selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                     // System.out.println (channel.toString () + "- Connected"); 
                }
                 // read data 
                IF (key.isReadable ()) { 
                    Channel the SocketChannel = (the SocketChannel) key.channel (); 
                    the ByteBuffer BF = ByteBuffer.allocate (1024 ); 
                    channel.read (BF); 
                    System.out.println ( "data from the client:" + new new String (bf.array ( )));
                     // only the first time a return message communication 
                    IF (isFirst) { 
                        isFirst= false;
                        ByteBuffer bst = ByteBuffer.wrap("Hi!".getBytes());
                        channel.write(bst);
                    }
                }
                //写数据
                if(key.isWritable()){
                    Scanner scanner = new Scanner(System.in);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String msg = sdf.format(new Date()) + "\t" + scanner.nextLine();
                    SocketChannel channel =(The SocketChannel) key.channel (); 
                    the ByteBuffer BST = ByteBuffer.wrap (Msg.getBytes ()); 
                    channel.write (BST); 
//                     key.interestOps (key.interestOps () & ~ SelectionKey.OP_WRITE); // cancel the write-ready, otherwise it would have been ready to write trigger 
                } 
                the Iterator.remove (); 
                
            } 
            
        } 
    } 
    
    public  static  void main (String [] args) {
         the try { 
            Server Server = new new Server (9999 ); 
        } the catch (IOException E) {
             / / TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
}

 

package com.demo.nio;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

public class Client {

    
    private SocketChannel sc = null;
    private Selector selector = null;
    
    public Client(int port) throws IOException {
        sc = SocketChannel.open();
        selector = Selector.open();
        sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), port));
        sc.configureBlocking(false);
        sc.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        ByteBuffer bf = ByteBuffer.wrap("Hello".getBytes());
        sc.write(bf);
        
        listener(selector);
    }
    
    private void listener(Selector selector) throws IOException{
        while(true){
            selector.select();
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            
            while(iterator.hasNext()){
                SelectionKey key = iterator.next();
                if(key.isReadable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer dst = ByteBuffer.allocate(1024);
                    channel.read(dst);
                    System.out.println("来自服务器:" + new String(dst.array()));
                }
                if(key.isWritable()){
                    Scanner scanner = new Scanner(System.in);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String msg = sdf.format(new Date()) + "\t" + scanner.nextLine();
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer bst = ByteBuffer.wrap(msg.getBytes());
                    channel.write(bst);
                }
                iterator.remove();
            }
            
        }
    }
    
    public static void main(String[] args) {
        try {
            Client client = new Client(9999);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

 

Examples of the above problems have been described in detail in a comment, do not believe you can run it, the following is a modified version, the write operation in a separate thread

package com.demo.nio;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 *  修正版
 */
public class ServerRevision {

    private boolean isFirst = true;
    private ServerSocketChannel ssc = null;
    private Selector selector = null;

    public ServerRevision(int port) throws IOException {
        ssc = ServerSocketChannel.open();
        selector = Selector.open();
        InetSocketAddress inetAddress = new InetSocketAddress(InetAddress.getLocalHost(), port);
        
        ssc.socket().bind(inetAddress);
        ssc.configureBlocking(false);
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        listener(selector);
    }
    
    private void listener(Selector selector) throws IOException{
        while(true){
            System.out.println("等待客户端连接...");
            selector.select();
            System.out.println("捕获客户端连接...");
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                //连接事件
                if(key.isAcceptable()){
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    channel.accept().configureBlocking(false).register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                    //System.out.println(channel.toString() + "-已连接");
                }
                //读数据
                if(key.isReadable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    BF the ByteBuffer = ByteBuffer.allocate (1024);
                    channel.read (BF); 
                    System.out.println ( "Data from the client:" + new new String (bf.array ()));
                     // only the first time a return message communication 
                    IF (isFirst) { 
                        isFirst = to false ; 
                        BST the ByteBuffer = ByteBuffer.wrap ( "the Hi!" .getBytes ()); 
                        channel.write (BST); 
                    } 
                } 
                // write data 
                IF (key.isWritable ()) { 
                    System.out.println ( "[server] write ready ... " );
                     new new the Thread ( new new DealWrite (Key)) Start ();. 
                    Key.interestOps (key.interestOps () & ~ SelectionKey.OP_WRITE); // cancel write-ready, otherwise it would have been ready to write trigger 
                } 
                the Iterator.remove () ; 
                
            } 
            
        } 
    } 
    
    public  static  void main (String [] args) {
         the try { 
            ServerRevision Server = new new ServerRevision (9999 ); 
        } the catch (IOException E) {
             // the TODO Auto Block the catch-Generated
             e.printStackTrace (); 
        } 
    } 

} 

class DealWrite implements Runnable{

    private SelectionKey key;

    public DealWrite(SelectionKey key) {
        this.key = key;
    }

    @Override
    public void run() {
        while (true){
            Scanner scanner = new Scanner(System.in);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String msg = sdf.format(new Date()) + "\t" + scanner.nextLine();
            SocketChannel channel = (SocketChannel) key.channel();
            ByteBuffer bst = ByteBuffer.wrap(msg.getBytes());
            try {
                channel.write(bst);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

package com.demo.nio;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * 修正版
 */
public class ClientRevision {


    private SocketChannel sc = null;
    private Selector selector = null;

    public ClientRevision(int port) throws IOException {
        sc = SocketChannel.open();
        selector = Selector.open();
        sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), port));
        sc.configureBlocking(false);
        sc.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        ByteBuffer bf = ByteBuffer.wrap("Hello".getBytes());
        sc.write(bf);
        
        listener(selector);
    }
    
    private void listener(Selector selector) throws IOException{
        while(true){
            selector.select();
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            
            while(iterator.hasNext()){
                SelectionKey key = iterator.next();
                if(key.isReadable()){
                    Channel the SocketChannel = (the SocketChannel) key.channel (); 
                    the ByteBuffer DST = ByteBuffer.allocate (1024 ); 
                    channel.read (DST); 
                    System.out.println ( "from the server:" + new new String (dst.array ()) ); 
                } 
                IF (key.isWritable ()) { 
                    System.out.println ( "[client] write-ready ..." );
                     new new the Thread ( new new DealWrite (Key)) Start ();. 
                    key.interestOps (Key .interestOps () & ~ SelectionKey.OP_WRITE); // cancel write-ready, otherwise it will always trigger the write-ready
                 } 
                the Iterator.remove ();
            }
            
        }
    }
    
    public static void main(String[] args) {
        try {
            ClientRevision client = new ClientRevision(9999);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

 

Currently only tested the server - client communication one to one, do not know a server for multiple clients what bug

 

NIO little more complicated it, but the core of the three-Selector, Channel, Buffer, NIO is synchronous non-blocking.

Guess you like

Origin www.cnblogs.com/LUA123/p/11389692.html