JAva単純チャットネットワークプログラミング

18978 ワード

demo 1(単一スレッド単純通信)ioストリーム
サービス側
public class Server {
    public static void main(String[] args) throws Exception {
        //5.  ServerSocket、Socket、OutputStream、InputStream         
        ServerSocket serverSocket = null;
        boolean flag = true;
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        try {
            //6.                
            serverSocket = new ServerSocket(8000);//        
            System.out.println("     ,    ...");
            socket = serverSocket.accept();//    
            //          
            in = socket.getInputStream();
            //7.                
            out = socket.getOutputStream();
            System.out.println(socket.getInetAddress().getHostAddress() + "---    ");
            out.write("    ".getBytes());
            out.flush();
            while (flag) {
                byte[] b = new byte[1024];
                int len = in.read(b);
                System.out.println("client:" + new String(b, 0, len));
                //     
                Scanner src = new Scanner(System.in);
                String str = src.nextLine();
                out.write(str.getBytes());
                out.flush();
                if (str.equals("bye")) {
                    flag = false;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //8.     、ServerSocket    Socket  
            in.close();
            out.close();
            serverSocket.close();
            socket.close();
        }
    }
}

クライアント
public class Client {
    public static void main(String[] args) throws Exception {
        //1.   Socket   、OutputStream       InputStream         
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        boolean flag = true;
        //        IP       
        String serverIP = "127.0.0.1";//     IP   
        int port = 8000;//       
        try {
            //2.                     
            socket = new Socket(serverIP, port);//    
            out = socket.getOutputStream();//    
            while (flag) {
                //3.                      
                byte[] b = new byte[1024];
                in = socket.getInputStream();
                int len = in.read(b);
                String response = new String(b, 0, len);
                System.out.println("server:" + response);
                if ("bye".equals(response)) {
                    flag = false;
                    break;
                }
                //     
                Scanner src = new Scanner(System.in);
                String str = src.nextLine();
                out.write(str.getBytes());
                out.flush();

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.     Socket   
            in.close();
            out.close();
            socket.close();
        }
    }
}

demo 1(単一スレッド単純通信)nio
サービス側
public class NIOServer {
    //        SocketChannel  
    private static  Map clientMap = new HashMap();

    private  static ByteBuffer sBuffer = ByteBuffer.allocate(1024);

    //      (Selector)
    private static Selector selector;

    public static void main(String[] args) throws IOException {
        //        (Selector)
        selector = Selector.open();

        //     ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //          
        serverSocketChannel.configureBlocking(false);

        //  ServerSocketChannel   ServerSocket       (port)
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(new InetSocketAddress(8000));
        /**
         *    (Channel)        (Selector),       selectionKey.OP_ACCEPT  
         *       ,        ,selector.select()   ,
         *         selector.select()     。
         */
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("         。。。");
        //     
        while (true) {
            //         ,    ,          
            selector.select();

            //       
            Set selectionKeys = selector.selectedKeys();
            Iterator iterator = selectionKeys.iterator();

            //     
            while (iterator.hasNext()) {
                //     
                SelectionKey key = iterator.next();
                //     ,      
                iterator.remove();

                //                        
                if (key.isAcceptable()) {
                    handleAccept(key);
                } else if (key.isReadable()) {//                
                    handleRead(key);
                }

            }


        }
    }

    /**
     *            
     */
    private static void handleAccept(SelectionKey key) throws IOException {
        //          
        ServerSocketChannel server = (ServerSocketChannel) key.channel();
        SocketChannel socketChannel = server.accept();
        socketChannel.configureBlocking(false);

        //             
        String msg = "    !";
        socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
        //            
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        sBuffer.clear();
                        //     
                        Scanner src = new Scanner(System.in);
                        String str = src.nextLine();
//                        System.out.println(sendText);
                        sBuffer.put(Charset.forName("UTF-8").encode(str));
                        sBuffer.flip();
                        socketChannel.write(sBuffer);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        clientMap.put(getClientName(socketChannel), socketChannel);
        //         ,          ,      
        socketChannel.register(selector, SelectionKey.OP_READ);
    }

    /**
     *       ,            
     */
    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        //            
        ByteBuffer buffer = ByteBuffer.allocate(128);
        channel.read(buffer);

        //             
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("client:" + channel.toString() + "   " + msg);
        //        
//        dispatch(channel, msg);
    }
    /**
     *           
     */
    private static void dispatch(SocketChannel client, String info) throws IOException {
        if (!clientMap.isEmpty()) {
            for (Map.Entry entry : clientMap.entrySet()) {
                SocketChannel temp = entry.getValue();
                if (!client.equals(temp)) {
                    sBuffer.clear();
                    sBuffer.put(Charset.forName("UTF-8").encode(getClientName(client) + ":" + info));
                    sBuffer.flip();
                    temp.write(sBuffer);
                }
            }
        }
    }

    /**
     *        
     */
    private static  String getClientName(SocketChannel client){
        Socket socket = client.socket();
        return "[" + socket.getInetAddress().toString().substring(1) + ":" + Integer.toHexString(client.hashCode()) + "]";
    }

}

クライアント

public class NIOClient {
    //      (Selector)
    private static Selector selector;
    private static Charset charset = Charset.forName("UTF-8");
 
    public static void main(String[] args) throws IOException {
        //        (Selector)
        selector = Selector.open();
 
        //     SocketChannel
        SocketChannel channel = SocketChannel.open();
        //          
        channel.configureBlocking(false);
 
        //         ,             ,   handleConnect    channel.finishConnect()      
        channel.connect(new InetSocketAddress("localhost", 8000));
 
        /**
         *    (Channel)        (Selector),       selectionKey.OP_CONNECT
         *       ,        ,selector.select()   ,
         *         selector.select()     。
         */
        channel.register(selector, SelectionKey.OP_CONNECT);
        //     
        while (true) {
            /*
             *         I/O     ,  selector ,           ,
             * selector wakeup     ,    ,        ,         
             *             ,  api      ,           。
             */
            selector.select();
 
            //       
            Set selectionKeys = selector.selectedKeys();
            Iterator iterator = selectionKeys.iterator();
 
            //     
            while (iterator.hasNext()) {
                //     
                SelectionKey key = iterator.next();
 
                //     ,      
                iterator.remove();
 
                //                      
                if (key.isConnectable()) {
                    handleConnect(key);
                } else if (key.isReadable()) {//                
                    handleRead(key);
                }
 
            }
        }
    }
 
    /**
     *               
     */
    private static void handleConnect(SelectionKey key) throws IOException {
        //              
        SocketChannel channel = (SocketChannel) key.channel();
        if (channel.isConnectionPending()) {
            // channel.finishConnect()      
            channel.finishConnect();
        }
 
        channel.configureBlocking(false);
        ByteBuffer sBuffer = ByteBuffer.allocate(1024);
        //       
        String msg = "Hello Server!";
        channel.write(ByteBuffer.wrap(msg.getBytes()));
        //            
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        sBuffer.clear();
                        //     
                        Scanner src = new Scanner(System.in);
                        String str = src.nextLine();
//                        System.out.println(sendText);
                        sBuffer.put(charset.encode(str));
                        sBuffer.flip();
                        channel.write(sBuffer);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        //         ,              
        channel.register(selector, SelectionKey.OP_READ);

    }
 
    /**
     *       ,            
     */
    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
 
        //            
        ByteBuffer buffer = ByteBuffer.allocate(128);
        channel.read(buffer);
 
        //               
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("server:" + msg);
    }
}

 
netty demo
サービス側構成
public class ServerChannelInitializer extends ChannelInitializer {

    @Override
    protected void initChannel(SocketChannel channel) {
        //       
//        channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
        //    String,           GBK、UTF-8
        channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
        //    String,           GBK、UTF-8
        channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
        //                    
        channel.pipeline().addLast(new MyServerHandler());
    }

}

serverコールバック処理
public class MyServerHandler extends SimpleChannelInboundHandler {

    public static HashMap channelList = new HashMap();

    /**
     *                ,          。                         
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel channel = (SocketChannel) ctx.channel();
        System.out.println("      ");
        System.out.println("      :            ");
        System.out.println("    IP:" + channel.localAddress().getHostString());
        System.out.println("    Port:" + channel.localAddress().getPort());
        System.out.println("      ");
        //           
        String str = "           " + " " + new Date() + " " + channel.localAddress().getHostString() + "\r
"; ctx.writeAndFlush(str); } /** * , 。 */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println(" " + ctx.channel().localAddress().toString()); } @Override public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { channelList.put("1",ctx.channel()); // msg { , } System.out.println(" client:" + msg); // { ByteBuf, } // String str = " :" + new Date() + " " + msg + "\r
"; // ctx.writeAndFlush(str); } /** * , , , 、 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println(" :\r
" + cause.getMessage()); } }

サーバ側起動
public class NettyServer {

    public static void main(String[] args) {
        new NettyServer().bing(7397);
    }

    private void bing(int port) {
        //     NIO   
        EventLoopGroup parentGroup = new NioEventLoopGroup(); //NioEventLoopGroup extends MultithreadEventLoopGroup Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
        EventLoopGroup childGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(parentGroup, childGroup)
                    .channel(NioServerSocketChannel.class)    //     
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childHandler(new ServerChannelInitializer());
            //    ,      .
            ChannelFuture f = b.bind(port).sync();
            System.out.println("netty server start done wait conn...");

            boolean flag=true;

            while (flag) {

                //     
                Scanner src = new Scanner(System.in);
                String str = src.nextLine();
                Channel channel= MyServerHandler.channelList.get("1");
                channel.writeAndFlush(str);
                if("byebye".equals(str)){
                    f.channel().close();
                    break;
                }
            }
            //           
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            childGroup.shutdownGracefully();
            parentGroup.shutdownGracefully();
        }

    }

}

クライアント
public class NettyClient {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
//        NioEventLoopGroup group = new NioEventLoopGroup();

       try{
           Bootstrap bootstrap = new Bootstrap();

           bootstrap.group(group)
                   .channel(NioSocketChannel.class)
                   .handler(new ChannelInitializer() {
                       @Override
                       protected void initChannel(Channel ch) {
//                           ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
                           ch.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
                           //    String,           GBK、UTF-8
                           ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
                           ch.pipeline().addLast(new ClientHandler());
                       }
                   });


           ChannelFuture future = bootstrap.connect("127.0.0.1", 7397).sync();
           boolean flag=true;
           while (flag) {
               //     
               Scanner src = new Scanner(System.in);
               String str = src.nextLine();
               future.channel().writeAndFlush(str);
               if("bye".equals(str)){
                   future.channel().close();
                   break;
               }
           }
           future.channel().closeFuture().sync();
       }finally {
           group.spliterator();
       }

    }

クライアントコールバック処理
public class ClientHandler extends SimpleChannelInboundHandler {

    /**
     *                ,          。                         
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel channel = (SocketChannel) ctx.channel();
        //           
//        String str = "           " + " " + new Date() + " " + channel.localAddress().getHostString() + "\r
"; System.out.println(" "); ctx.writeAndFlush(""); } /** * , 。 */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println(" " + ctx.channel().localAddress().toString()); } @Override public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { // msg { , } System.out.println( "server:" + msg); // { ByteBuf, } String str = "-- --" + "\r
"; ctx.writeAndFlush(str); } /** * , , , 、 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println(" :\r
" + cause.getMessage()); } }