Java NIO实现聊天功能
程序员文章站
2022-03-15 19:21:39
本文实例为大家分享了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.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。