欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java NIO实现聊天功能

程序员文章站 2022-06-26 17:06:16
本文实例为大家分享了java nio实现聊天功能的具体代码,供大家参考,具体内容如下server code : package com.tch.test.nio; import java.io.ioe...

本文实例为大家分享了java nio实现聊天功能的具体代码,供大家参考,具体内容如下

server code : 

package com.tch.test.nio;
 
import java.io.ioexception;
import java.net.inetsocketaddress;
import java.nio.bytebuffer;
import java.nio.channels.closedchannelexception;
import java.nio.channels.selectionkey;
import java.nio.channels.selector;
import java.nio.channels.serversocketchannel;
import java.nio.channels.socketchannel;
import java.util.arraylist;
import java.util.iterator;
import java.util.list;
import java.util.set;
 
public class nioserver {
 
 private socketchannel socketchannel = null;
 private set<selectionkey> selectionkeys = null;
 private iterator<selectionkey> iterator = null;
 private iterator<socketchannel> iterator2 = null;
 private selectionkey selectionkey = null;
 
 public static void main(string[] args) {
  new nioserver().start();
 }
 
 private void start(){
  try {
   //create serversocketchannel
   serversocketchannel serversocketchannel = serversocketchannel.open();
   //bind the serversocketchannel to a port
   serversocketchannel.bind(new inetsocketaddress(7878));
   //when using selector ,should config the blocking mode of serversocketchannel to non-blocking
   serversocketchannel.configureblocking(false);
   //create a selector to manage all the channels
   selector selector = selector.open();
   //reigst the serversocketchannel to the selector(interest in accept event)
   serversocketchannel.register(selector, selectionkey.op_accept);
   //create a list to store all the socketchannels
   list<socketchannel> clients = new arraylist<socketchannel>();
   //create a bytebuffer to store data
   bytebuffer buffer = bytebuffer.allocate(1024);
   while(true){
    //this method will block until at least one of the interested events is ready 
    int ready = selector.select();
    if(ready > 0){//means at least one of the interested events is ready 
     selectionkeys = selector.selectedkeys();
     iterator = selectionkeys.iterator();
     while(iterator.hasnext()){
                        //the selectionkey contains the channel and the event which the channel is interested in 
                        selectionkey = iterator.next();
                        //accept event , means new client reaches
                        if(selectionkey.isacceptable()){
                            //handle new client
                            serversocketchannel serversocketchannel2 = (serversocketchannel)selectionkey.channel();
                            socketchannel = serversocketchannel2.accept();
                            //when using selector , should config the blocking mode of socketchannel to non-blocking
                            socketchannel.configureblocking(false);
                            //regist the socketchannel to the selector
                            socketchannel.register(selector, selectionkey.op_read);
                            //add to client list
                            clients.add(socketchannel);
                        }else if(selectionkey.isreadable()){
                            //read message from client
                            socketchannel = (socketchannel)selectionkey.channel();
                            buffer.clear();
                            try {
                                socketchannel.read(buffer);
                                buffer.flip();
                                //send message to every client
                                iterator2 = clients.iterator();
                                socketchannel socketchannel2 = null;
                                while(iterator2.hasnext()){
                                    socketchannel2 = iterator2.next();
                                    while(buffer.hasremaining()){
                                        socketchannel2.write(buffer);
                                    }
                                    //rewind method makes the buffer ready to the next read operation
                                    buffer.rewind();
                                }
                            } catch (ioexception e) {
                                // ioexception occured on the channel, remove from channel list
                                e.printstacktrace();
                                // note: close the channel
                                socketchannel.close();
                                iterator2 = clients.iterator();
                                while(iterator2.hasnext()){
                                    if(socketchannel == iterator2.next()){
                                        // remove the channel
                                        iterator2.remove();
                                        system.out.println("remove the closed channel from client list ...");
                                        break;
                                    }
                                }
                            }
                        }
                        //important , remember to remove the channel after all the operations. so that the next selector.select() will 
                        //return this channel again .
      iterator.remove();
     }
    }
   }
  } catch (closedchannelexception e) {
   e.printstacktrace();
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }
 
}

client code : 

package com.tch.nio.test;
 
import java.awt.gridlayout;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
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.util.iterator;
import java.util.set;
 
import javax.swing.jbutton;
import javax.swing.jframe;
import javax.swing.jtextarea;
import javax.swing.jtextfield;
 
public class nioclient extends jframe{
 
 private static final long serialversionuid = 1l;
 private jtextarea area = new jtextarea("content :");
 private jtextfield textfield = new jtextfield("textfield:");
 private jbutton button = new jbutton("send");
 private socketchannel socketchannel = null;
 private bytebuffer buffer = bytebuffer.allocate(1024);
 private bytebuffer buffer2 = bytebuffer.allocate(1024);
 private string message = null;
 
 public static void main(string[] args) throws exception {
  nioclient client = new nioclient();
  client.start();
 }
 
 private void start() throws ioexception{
  setbounds(200, 200, 300, 400);
  setlayout(new gridlayout(3, 1));
  add(area);
  add(textfield);
  //create a socketchannel and connect to the specified address
  socketchannel = socketchannel.open(new inetsocketaddress("localhost", 7878));
  //when using selector , should config the blocking mode of socketchannel to non-blocking
  socketchannel.configureblocking(false);
  button.addactionlistener(new actionlistener() {
   @override
   public void actionperformed(actionevent event) {
    try {
     message = textfield.gettext();
     textfield.settext("");
     //send message to server
     buffer.put(message.getbytes("utf-8"));
     buffer.flip();
     while(buffer.hasremaining()){
      socketchannel.write(buffer);
     }
     buffer.clear();
    } catch (exception e) {
     e.printstacktrace();
    }
   }
  });
  add(button);
  setdefaultcloseoperation(exit_on_close);
  setvisible(true);
  set<selectionkey> selectionkeys = null;
  iterator<selectionkey> iterator = null;
  selectionkey selectionkey = null;
  selector selector = selector.open();
  //reigst the socketchannel to the selector(interest in read event)
  socketchannel.register(selector, selectionkey.op_read);
  while(true){
   //this method will block until at least one of the interested events is ready 
   int ready = selector.select();
   if(ready > 0){//means at least one of the interested events is ready 
    selectionkeys = selector.selectedkeys();
    iterator = selectionkeys.iterator();
    while(iterator.hasnext()){
     selectionkey = iterator.next();
     //read message from server ,then append the message to textarea
     if(selectionkey.isreadable()){
      socketchannel.read(buffer2);
      buffer2.flip();
      area.settext(area.gettext().trim()+"\n"+new string(buffer2.array(),0,buffer2.limit(),"utf-8"));
      buffer2.clear();
     }
     //important , remember to remove the channel after all the operations. so that the next selector.select() will 
     //return this channel again .
     iterator.remove();
    }
   }
  }
 }
 
}

run server first , then is client , type message and send , ok

使用mina实现聊天:

server:

package com.tch.test.jms.origin.server;
 
import java.io.ioexception;
import java.net.inetsocketaddress;
import java.nio.charset.charset;
import java.util.arraylist;
import java.util.list;
 
import org.apache.mina.core.service.ioacceptor;
import org.apache.mina.core.service.iohandleradapter;
import org.apache.mina.core.session.idlestatus;
import org.apache.mina.core.session.iosession;
import org.apache.mina.filter.codec.protocolcodecfilter;
import org.apache.mina.filter.codec.textline.textlinecodecfactory;
import org.apache.mina.filter.logging.loggingfilter;
import org.apache.mina.transport.socket.nio.niosocketacceptor;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
 
public class myserver {
 
 private static final logger logger = loggerfactory.getlogger(myserver.class);
 private list<iosession> clientsessionlist = new arraylist<iosession>();
 
 public static void main(string[] args) {
     
  ioacceptor acceptor = new niosocketacceptor();
 
  acceptor.getfilterchain().addlast("logger", new loggingfilter());
  acceptor.getfilterchain().addlast("codec", new protocolcodecfilter(new textlinecodecfactory(charset.forname("utf-8"))));
 
  acceptor.sethandler(new myserver().new myserveriohandler());
  
  try {
   acceptor.bind(new inetsocketaddress(10000));
  } catch (ioexception ex) {
   logger.error(ex.getmessage(), ex);
  }
 }
 
 class myserveriohandler extends iohandleradapter{
        
        @override
        public void sessioncreated(iosession session) throws exception {
            logger.info("sessioncreated");
        }
        
        @override
        public void sessionopened(iosession session) throws exception {
            logger.info("sessionopened");
            if(! clientsessionlist.contains(session)){
                clientsessionlist.add(session);
            }
        }
 
        @override
        public void sessionclosed(iosession session) throws exception {
            logger.info("sessionclosed");
            clientsessionlist.remove(session);
        }
 
        @override
        public void sessionidle(iosession session, idlestatus status) throws exception {
            logger.info("sessionidle");
        }
 
        @override
        public void exceptioncaught(iosession session, throwable cause) throws exception {
            logger.error(cause.getmessage(), cause);
            session.close(true);
            clientsessionlist.remove(session);
        }
 
        @override
        public void messagereceived(iosession session, object message) throws exception {
            logger.info("messagereceived:" + message);
            for(iosession clientsession : clientsessionlist){
                clientsession.write(message);
            }
        }
 
        @override
        public void messagesent(iosession session, object message) throws exception {
            logger.info("messagesent:" + message);
        }
    }
}

client :

package com.tch.test.jms.origin.client;
 
import java.awt.gridlayout;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.io.ioexception;
import java.net.inetsocketaddress;
import java.nio.charset.charset;
 
import javax.swing.jbutton;
import javax.swing.jframe;
import javax.swing.jtextarea;
import javax.swing.jtextfield;
 
import org.apache.mina.core.runtimeioexception;
import org.apache.mina.core.future.connectfuture;
import org.apache.mina.core.service.ioconnector;
import org.apache.mina.core.service.iohandleradapter;
import org.apache.mina.core.session.idlestatus;
import org.apache.mina.core.session.iosession;
import org.apache.mina.filter.codec.protocolcodecfilter;
import org.apache.mina.filter.codec.textline.textlinecodecfactory;
import org.apache.mina.filter.logging.loggingfilter;
import org.apache.mina.transport.socket.nio.niosocketconnector;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
 
public class nioclient extends jframe{
    private static final logger logger = loggerfactory.getlogger(nioclient.class);
 private static final long serialversionuid = 1l;
 private jtextarea area = new jtextarea("content :");
 private jtextfield textfield = new jtextfield("textfield:");
 private jbutton button = new jbutton("send");
 private string message = null;
 private myclientiohandler handler;
 private iosession session;
 
 public static void main(string[] args) throws exception {
  nioclient client = new nioclient();
  client.start();
 }
 
 private void start() throws ioexception{
  setbounds(200, 200, 300, 400);
  setlayout(new gridlayout(3, 1));
  add(area);
  add(textfield);
  
  ioconnector connector = new niosocketconnector();
        connector.setconnecttimeoutmillis(10 * 1000);
        
        connector.getfilterchain().addlast("logger", new loggingfilter());
        connector.getfilterchain().addlast("codec", new protocolcodecfilter(new textlinecodecfactory(charset.forname("utf-8"))));
        
        handler = new myclientiohandler(this);
        connector.sethandler(handler);
  
  button.addactionlistener(new actionlistener() {
   @override
   public void actionperformed(actionevent event) {
       sendmessage();
   }
  });
  add(button);
  setdefaultcloseoperation(exit_on_close);
  setvisible(true);
  
  iosession session = null;
        try {
            connectfuture future = connector.connect(new inetsocketaddress("localhost", 10000));
            future.awaituninterruptibly();
            session = future.getsession();
        } catch (runtimeioexception e) {
            logger.error(e.getmessage(), e);
        }
        session.getclosefuture().awaituninterruptibly();
        connector.dispose();
 }
 
 private void sendmessage() {
        try {
            message = textfield.gettext();
            textfield.settext("");
            if(session == null || ! session.isconnected()){
                throw new runtimeexception("session is null");
            }
            session.write(message);
        } catch (exception e) {
            e.printstacktrace();
        }
    }
 
 class myclientiohandler extends iohandleradapter{
     private nioclient client;
        public myclientiohandler(nioclient client){
            this.client = client;
        }
        @override
        public void sessioncreated(iosession session) throws exception {
            logger.info("sessioncreated");
        }
 
        @override
        public void sessionopened(iosession session) throws exception {
            logger.info("sessionopened");
            client.session = session;
        }
 
        @override
        public void sessionclosed(iosession session) throws exception {
            logger.info("sessionclosed");
        }
 
        @override
        public void sessionidle(iosession session, idlestatus status) throws exception {
            logger.info("sessionidle");
        }
 
        @override
        public void exceptioncaught(iosession session, throwable cause) throws exception {
            logger.error(cause.getmessage(), cause);
            session.close(true);
        }
 
        @override
        public void messagereceived(iosession session, object message) throws exception {
            logger.info("messagereceived: " + message);
            if (message.tostring().equalsignorecase("bye")) {
                session.close(true);
            }
            area.settext(area.gettext().trim()+"\n"+message);
        }
 
        @override
        public void messagesent(iosession session, object message) throws exception {
            logger.info("messagesent: " + message);
        }
    }
 
}

ok.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: Java NIO 聊天