자바 NIO 예시:다 중 인터넷 채 팅 방

29445 단어 java NIO
다 중 클 라 이언 트 채 팅 방 으로 다 중 클 라 이언 트 채 팅 을 지원 합 니 다.다음 과 같은 기능 이 있 습 니 다.
  • 기능 1:클 라 이언 트 가 자바 NIO 를 통 해 서버 에 연결 되 고 다 중 클 라 이언 트 의 연결 을 지원 합 니 다
  • 기능 2:클 라 이언 트 가 처음 연결 할 때 서버 에서 닉네임 을 입력 하 라 고 알려 줍 니 다.닉네임 을 사용 한 사람 이 있 으 면 다시 입력 하 라 고 알려 줍 니 다.닉네임 이 유일 하면 로그 인 에 성 공 했 습 니 다.그 후에 메 시 지 를 보 낼 때 정 해진 형식 으로 닉네임 을 가지 고 메 시 지 를 보 내야 합 니 다
  • 기능 3:클 라 이언 트 가 로그 인 한 후에 설 정 된 환영 정보 와 온라인 인원 을 클 라 이언 트 에 게 보 내 고 다른 클 라 이언 트 에 게 이 클 라 이언 트 가 접속 하 는 것 을 알 립 니 다
  • 기능 4:서버 는 이미 로그 인 한 클 라 이언 트 의 입력 내용 을 받 아 다른 로그 인 클 라 이언 트 에 전송 합 니 다.
  • 기능 5 TODO:클 라 이언 트 오프라인 검색 방안 은 클 라 이언 트 가 온라인 에 있 을 때 심장 박동 을 보 내 고 서버 에서 TimeCacheMap 으로 기한 이 지난 대상 을 자동 으로 삭제 하 는 동시에 온라인 사용자 에 게 삭 제 된 사용자 의 오프라인 을 알 리 는 것 입 니 다.

  • 다음은 효 과 를 보 여 드 리 겠 습 니 다.코드 는 부록 을 보십시오!
     
    서버 를 시작 하여 포트 를 감청 합 니 다.
    서버 콘 솔
    Server is listening now...

     
    클 라 이언 트 시작,서버 연결
    서버 콘 솔
    Server is listening now...
    Server is listening from client :/127.0.0.1:50206

    클 라 이언 트 콘 솔
    Please input your name.

     
    클 라 이언 트 닉네임 입력
    서버 콘 솔
    Server is listening now...
    Server is listening from client :/127.0.0.1:50206
    Server is listening from client /127.0.0.1:50206 data rev is: byr1#@#

    클 라 이언 트 콘 솔
    Please input your name.
    byr1
    welcome byr1 to chat room! Online numbers:1

     
    다른 클 라 이언 트 를 시작 하고 닉네임 을 입력 하 십시오.
    서버 콘 솔
    Server is listening now...
    Server is listening from client :/127.0.0.1:50206
    Server is listening from client /127.0.0.1:50206 data rev is: byr1#@#
    Server is listening from client :/127.0.0.1:50261
    Server is listening from client /127.0.0.1:50261 data rev is: byr2#@#

    클 라 이언 트 byr 1 콘 솔
    Please input your name.
    byr1
    welcome byr1 to chat room! Online numbers:1
    welcome byr2 to chat room! Online numbers:2

    클 라 이언 트 byr 2 console
    Please input your name.
    byr2
    welcome byr2 to chat room! Online numbers:2

     
    클 라 이언 트 byr 1 에서 메 시 지 를 보 내 고 클 라 이언 트 byr 2 에서 메 시 지 를 보 냅 니 다.
    서버 콘 솔
    Server is listening now...
    Server is listening from client :/127.0.0.1:50206
    Server is listening from client /127.0.0.1:50206 data rev is: byr1#@#
    Server is listening from client :/127.0.0.1:50261
    Server is listening from client /127.0.0.1:50261 data rev is: byr2#@#
    Server is listening from client /127.0.0.1:50206 data rev is: byr1#@#hello byr2, a nice day, isn't it?
    Server is listening from client /127.0.0.1:50261 data rev is: byr2#@#fine

    클 라 이언 트 byr 1 콘 솔
    Please input your name.
    byr1
    welcome byr1 to chat room! Online numbers:1
    welcome byr2 to chat room! Online numbers:2
    hello byr2, a nice day, isn't it?
    byr2 say fine

    클 라 이언 트 byr 2 console
    Please input your name.
    byr2
    welcome byr2 to chat room! Online numbers:2
    byr1 say hello byr2, a nice day, isn't it?
    fine

     
    부록:server 와 client 코드
    서버 코드
    package com.huahuiyang.channel;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.Channel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.charset.Charset;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    /**
     *          
     *   1:      Java NIO      ,         
     *   2:        ,         ,          ,      ,      ,     ,                       
     *   3:      ,                     ,               
     *   4:               ,          。
     * 
     * TODO        
     */
    public class ChatRoomServer {
    
        private Selector selector = null;
        static final int port = 9999;
        private Charset charset = Charset.forName("UTF-8");
        //
        private static HashSet<String> users = new HashSet<String>();
        
        private static String USER_EXIST = "system message: user exist, please change a name";
        //
        private static String USER_CONTENT_SPILIT = "#@#";
        
        private static boolean flag = false;
        
        public void init() throws IOException
        {
            selector = Selector.open();
            ServerSocketChannel server = ServerSocketChannel.open();
            server.bind(new InetSocketAddress(port));
            //      
            server.configureBlocking(false);
            //
            server.register(selector, SelectionKey.OP_ACCEPT);
            
            System.out.println("Server is listening now...");
            
            while(true) {
                int readyChannels = selector.select();
                if(readyChannels == 0) continue; 
                Set selectedKeys = selector.selectedKeys();  //
                Iterator keyIterator = selectedKeys.iterator();
                while(keyIterator.hasNext()) {
                     SelectionKey sk = (SelectionKey) keyIterator.next();
                     keyIterator.remove();
                     dealWithSelectionKey(server,sk);
                }
            }
        }
        
        public void dealWithSelectionKey(ServerSocketChannel server,SelectionKey sk) throws IOException {
            if(sk.isAcceptable())
            {
                SocketChannel sc = server.accept();
                //     
                sc.configureBlocking(false);
                //     ,        ,        ,     SocketChannel,    selector ,         ,    SocketChannel  
                sc.register(selector, SelectionKey.OP_READ);
                
                //     channel              
                sk.interestOps(SelectionKey.OP_ACCEPT);
                System.out.println("Server is listening from client :" + sc.getRemoteAddress());
                sc.write(charset.encode("Please input your name."));
            }
            //              
            if(sk.isReadable())
            {
                //   SelectionKey    Channel,         
                SocketChannel sc = (SocketChannel)sk.channel(); 
                ByteBuffer buff = ByteBuffer.allocate(1024);
                StringBuilder content = new StringBuilder();
                try
                {
                    while(sc.read(buff) > 0)
                    {
                        buff.flip();
                        content.append(charset.decode(buff));
                        
                    }
                    System.out.println("Server is listening from client " + sc.getRemoteAddress() + " data rev is: " + content);
                    //     channel            
                    sk.interestOps(SelectionKey.OP_READ);
                }
                catch (IOException io)
                {
                    sk.cancel();
                    if(sk.channel() != null)
                    {
                        sk.channel().close();
                    }
                }
                if(content.length() > 0)
                {
                    String[] arrayContent = content.toString().split(USER_CONTENT_SPILIT);
                    //    
                    if(arrayContent != null && arrayContent.length ==1) {
                        String name = arrayContent[0];
                        if(users.contains(name)) {
                            sc.write(charset.encode(USER_EXIST));
                            
                        } else {
                            users.add(name);
                            int num = OnlineNum(selector);
                            String message = "welcome "+name+" to chat room! Online numbers:"+num;
                            BroadCast(selector, null, message);
                        }
                    } 
                    //
                    else if(arrayContent != null && arrayContent.length >1){
                        String name = arrayContent[0];
                        String message = content.substring(name.length()+USER_CONTENT_SPILIT.length());
                        message = name + " say " + message;
                        if(users.contains(name)) {
                            //             
                            BroadCast(selector, sc, message);
                        }
                    }
                }
                
            }
        }
        
        //TODO        ,        
        public static int OnlineNum(Selector selector) {
            int res = 0;
            for(SelectionKey key : selector.keys())
            {
                Channel targetchannel = key.channel();
                
                if(targetchannel instanceof SocketChannel)
                {
                    res++;
                }
            }
            return res;
        }
        
        public void BroadCast(Selector selector, SocketChannel except, String content) throws IOException {
            //        SocketChannel 
            for(SelectionKey key : selector.keys())
            {
                Channel targetchannel = key.channel();
                //  except   ,             
                if(targetchannel instanceof SocketChannel && targetchannel!=except)
                {
                    SocketChannel dest = (SocketChannel)targetchannel;
                    dest.write(charset.encode(content));
                }
            }
        }
        
        public static void main(String[] args) throws IOException 
        {
            new ChatRoomServer().init();
        }
    }

     
    클 라 이언 트 코드
    package com.huahuiyang.channel;
    
    import java.io.IOException;
    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.nio.charset.Charset;
    import java.util.Iterator;
    import java.util.Scanner;
    import java.util.Set;
    
    
    public class ChatRoomClient {
    
        private Selector selector = null;
        static final int port = 9999;
        private Charset charset = Charset.forName("UTF-8");
        private SocketChannel sc = null;
        private String name = "";
        private static String USER_EXIST = "system message: user exist, please change a name";
        private static String USER_CONTENT_SPILIT = "#@#";
        
        public void init() throws IOException
        {
            selector = Selector.open();
            //       IP   
            sc = SocketChannel.open(new InetSocketAddress("127.0.0.1",port));
            sc.configureBlocking(false);
            sc.register(selector, SelectionKey.OP_READ);
            //                  
            new Thread(new ClientThread()).start();
            //                    
            Scanner scan = new Scanner(System.in);
            while(scan.hasNextLine())
            {
                String line = scan.nextLine();
                if("".equals(line)) continue; //       
                if("".equals(name)) {
                    name = line;
                    line = name+USER_CONTENT_SPILIT;
                } else {
                    line = name+USER_CONTENT_SPILIT+line;
                }
                sc.write(charset.encode(line));//sc      ,    
            }
            
        }
        private class ClientThread implements Runnable
        {
            public void run()
            {
                try
                {
                    while(true) {
                        int readyChannels = selector.select();
                        if(readyChannels == 0) continue; 
                        Set selectedKeys = selector.selectedKeys();  //
                        Iterator keyIterator = selectedKeys.iterator();
                        while(keyIterator.hasNext()) {
                             SelectionKey sk = (SelectionKey) keyIterator.next();
                             keyIterator.remove();
                             dealWithSelectionKey(sk);
                        }
                    }
                }
                catch (IOException io)
                {}
            }
    
            private void dealWithSelectionKey(SelectionKey sk) throws IOException {
                if(sk.isReadable())
                {
                    //   NIO    Channel    ,       sc    ,        SocketChannel
                    //sc      ,    
                    SocketChannel sc = (SocketChannel)sk.channel();
                    
                    ByteBuffer buff = ByteBuffer.allocate(1024);
                    String content = "";
                    while(sc.read(buff) > 0)
                    {
                        buff.flip();
                        content += charset.decode(buff);
                    }
                    //
                    if(USER_EXIST.equals(content)) {
                        name = "";
                    }
                    System.out.println(content);
                    sk.interestOps(SelectionKey.OP_READ);
                }
            }
        }
        
        
        
        public static void main(String[] args) throws IOException
        {
            new ChatRoomClient().init();
        }
    }

     

    좋은 웹페이지 즐겨찾기