Java NiO Example: Multi-person Network chat Room

Source: Internet
Author: User

A multi-client chat room, support multi-client chat, like the following features:

    • Feature 1: Client connects to the server via Java NIO, supports multiple client connections
    • Function 2: When the client initial connection, the server prompts for a nickname, if the nickname has been used, prompt re-enter, if the nickname is unique, the login is successful, and then send the message will need to follow the specified format with a nickname to send messages
    • Feature 3: After the client logs in, send the welcome information and the number of people online to the client, and notify the other clients that the client is online
    • Function 4: The server receives the logged-in client input and forwards it to the other login clients.
    • Function 5 TODO: Client offline detection scheme is: The client online time to send heartbeat, the service end with Timecachemap automatically delete expired objects, and notify the user on the line deleted users offline.

The following shows the effect, code see Appendix!

Start the server, listen to a port

Server Console

Server is listening now ...

Start a client, connect to the server

Server Console

Server is listening now ... Server is listening from client:/127.0.  0.1:50206  

Client Console

Please input your name.

Client input a nickname

Server Console

Server is listening now ... Server is listening from client:/127.0.  0.1:50206Server is listening from client/127.0.  0.1:50206 Data rev is:byr1#@#      

Client Console

Please input your name.byr1welcome byr1 to chat room! Online numbers:1

Start another client and enter a nickname

Server Console

Server is listening now ... Server is listening from client:/127.0.  0.1:50206Server is listening from client/127.0.  0.1:50206 Data rev is:byr1#@ #Server is listening from client:/127.0.  0.1:50261Server is listening from client/127.0.  0.1:50261 Data rev is:byr2#@#              

Client BYR1 Console

Please input your name.byr1welcome byr1 to chat room! Online numbers:1welcome byr2 to chat room! Online numbers:2  

Client BYR2 Console

Please input your name.byr2welcome byr2 to chat room! Online numbers:2

Client BYR1 sends a message that the customer BYR2 back a message

Server Console

Server is listening now ... Server is listening from client:/127.0.0.1:50206Server is listening from client/127.0.0.1:50206 data rev is:byr1#@ #Server is listening from client:/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< Span style= "color: #800000;" > ' 

Client BYR1 Console

Please input your name.byr1welcome byr1 to chat room! Online numbers:1welcome byr2 to chat room! Online numbers:2 Nice day, isn't it?byr2 say fine     

Client BYR2 Console

Please input your name.byr2welcome byr2 to chat room! Online numbers:2 Nice day, isn't it?fine   

Appendix: Server and Client code

Server Code

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;/** * Network multi-client Chat room * Function 1: The client connects to the server through Java NIO, support multi-Client connection * Function 2: When the client initial connection, the server prompts for a nickname, if the nickname has been used, prompt re-enter, if the nickname is unique, then login successful, After sending a message, you need to send a message with your nickname in the required format * Function 3: After the client logs in, send the welcome information and the number of people online to the client, and notify the other clients that the client is online * Function 4: The server receives the logged-in client input and forwards it to the other login clients.    * * TODO Client Offline detection */public class Chatroomserver {private Selector Selector = null;    static final int port = 9999;    Private Charset Charset = Charset.forname ("UTF-8");        Used to record the number of people online, as well as the nickname private static hashset<string> users = new hashset<string> ();    private static String user_exist = "System Message:user EXIST, please change a name"; //Equivalent to the custom protocol format, negotiate with the client good 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));        Non-blocking mode server.configureblocking (false);                Register to the selector, set to listening status 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 ();            This method allows you to know the set of available channels 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 ();            Non-blocking mode sc.configureblocking (false); Registers the selector and sets it to read mode, receives a connection request, then plays a socketchannel, and registers to selector, after which the data for this connection is processed by this socketchannel sc.register (selector,                        Selectionkey.op_read);            Set this corresponding channel to be ready to accept other client requests sk.interestops (SELECTIONKEY.OP_ACCEPT);            System.out.println ("Server is listening from client:" + sc.getremoteaddress ());        Sc.write (Charset.encode ("Please input your name.");            }//Handles data read requests from the client if (sk.isreadable ()) {//returns the Selectionkey corresponding Channel, where the data needs to be read             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:" + conten                T);            Set this corresponding channel to prepare the next accepted data 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); Registered user if (arraycontent! = null && arraycontent.length ==1) {String name = array                    CONTENT[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); }}//register finished, send 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)) {///does not reply to the client sending this content broadcast (selector, SC, message); }}}}//todo If you can detect the downline, you don't have to count the public STA        Tic int onlinenum (Selector Selector) {int res = 0; for (SelectionkeyKey:selector.keys ()) {Channel Targetchannel = Key.channel ();            if (Targetchannel instanceof Socketchannel) {res++;    }} return res; } public void Broadcast (Selector Selector, socketchannel except, String content) throws IOException {//Broadcast data To all Socketchannel for (Selectionkey Key:selector.keys ()) {Channel Targetchannel = Key.channel (            );            If except is not empty, the client sending this content is not sent back 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 (); }}

 client Code

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 ();        Connect the remote host IP and Port sc = socketchannel.open (new inetsocketaddress ("127.0.0.1", port));        Sc.configureblocking (FALSE);        Sc.register (selector, selectionkey.op_read);       Opens up a new thread to read data from the server side New Thread (New Clientthread ()). Start ();        Read data input from the keyboard in the main thread to server-side Scanner scan = new Scanner (system.in);            while (Scan.hasnextline ()) {String line = Scan.nextline (); if ("". Equals (line)) continue;                Do not allow empty messages if ("". Equals (name)) {name = line;            line = Name+user_content_spilit;            } else {line = Name+user_content_spilit+line;  } sc.write (line),//SC can both write and read, this is write}} private class Clientthread implements                    Runnable {public void run () {try {while (true) {                    int readychannels = Selector.select ();                     if (Readychannels = = 0) continue;  Set Selectedkeys = Selector.selectedkeys ();                    This method allows you to know the set of available channels Iterator Keyiterator = Selectedkeys.iterator ();               while (Keyiterator.hasnext ()) {          Selectionkey SK = (Selectionkey) keyiterator.next ();                         Keyiterator.remove ();                    Dealwithselectionkey (SK); }}} catch (IOException io) {}} private void Dealwithselec Tionkey (Selectionkey sk) throws IOException {if (sk.isreadable ()) {//read with NIO Chann The data in El, this and the global variable SC is the same, because only registered a Socketchannel//SC can write can read, this is read Socketchannel sc = (socketchannel                                ) Sk.channel ();                Bytebuffer buff = bytebuffer.allocate (1024);                String content = "";                    while (Sc.read (buff) > 0) {buff.flip ();                Content + = Charset.decode (buff);                }//If the system sends a notification name already exists, you need to change the nickname 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 (); }}

Java NiO Example: Multi-person Network chat Room

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.