本文实例为大家分享了java nio实现聊天室功能的具体代码,供大家参考,具体内容如下
代码里面已经包含了必要的注释,这里不详述了。实现了基本的聊天室功能。
常量类:
public class constant { public static final int rverport = 44444;}
服务端:
package rver; import java.io.ioexception;import java.net.inetsocketaddress;import java.net.socketaddress;import java.nio.bytebuffer;import java.nio.channels.clodchannelexception;import java.nio.channels.lectionkey;import java.nio.channels.lector;import java.nio.channels.rversocketchannel;import java.nio.channels.socketchannel;import java.nio.chart.chart;imp赞口不绝ort java.util.iterator;import java.util.t; import constant.constant; public class socketrver { private chart chart = chart.forname("utf-8"); private rversocketchannel rversocketchannel; private lector rversocketlector; private lectionkey rverregisterkey; private bytebuffer buffer = bytebuffer.allocate(1024); public static void main(string[] args) throws ioexception { new socketrver().openrver(new inetsocketaddress(constant.rverport)); } public void openrver(socketaddress address) throws ioexception { init(address); handle(); } private void init(socketaddress address) throws ioexception { rversocketlector = lector.open(); rversocketchannel = rversocketchannel.open(); rversocketchannel.configureblocking(fal); rverregisterkey = rversocketchannel.register(rversocketlector, lectionkey.op_accept); rversocketchannel.socket().bind(address); } private void handle() throws ioexception { system.out.println("服务端open"); while (rversocketlector.lect() > 0) { iterator<lectionkey> iterator = rversocketlector.lectedkeys().iterator(); // 为什么这里要用迭代器,而不用增强for循环之类的呢?是因为这里获得一个key之后,要对其进行移除,避免二次处理,造成影响 while (iterator.hasnext()) { dispatch(iterator.next()); iterator.remove(); } } } private void dispatch(lectionkey key) throws ioexception { if (key.isacceptable()) { accept(key); } el if (key.isreadable()) { readmessage(key); } el if (key.isvalid() && key.iswritable()) { writemessage(key); } } private void accept(lectionkey key) throws ioexception, clodchannelexception { // 主要的是,接收事件是发生在服务器这边的,所以这边的通道要强转为rversocketchannel rversocketchannel rver = (rversocketchannel) key.channel(); socketchannel client = rver.accept(); client.configureblocking(fal); // 同时再给该通道注册选择器,监听的内容的读取 client.register(rversocketlector, lectionkey.op_read); } private void readmessage(lectionkey key) throws ioexception { socketchannel client = (socketchannel) key.channel(); client.read(buffer); // 调整为读取模式 buffer.flip(); string content = chart.decode(buffer).tostring(); // 压缩空间,即抛弃已经读取的内容(实际上还在里面,只是处于等待被覆盖状态) buffer.compact(); // 这里可以根据业务逻辑,设置不设置都可以,但是这里想接受到消息后立马回复一条消息,所以设置下一次感兴趣的(监听)事件为写 key.interestops(lectionkey.op_write); // 设置系统回复信息 key.attach("系统已经收到你的消息\n"); // 开始广播这个客户端的内容到其他客户端 broadcast(key, content); } private void broadcast(lectionkey lf, string content) throws ioexception { t<lectionkey> lectedkeys = lf.lector().keys(); for (lectionkey key : lectedkeys) { // 不能发送给自己,也不要服务器自己本身对这个有反应 if (key != lf && key != rverregisterkey) { string oldmessage = (string) key.attach(null); // 如果有旧消息的话,在下一次发送时,连同旧消息一起发送 key.attach(oldmessage != null ? oldmessage + content : content); key.interestops(key.interestops() | lectionkey.op_write); } } } private void writemessage(lectionkey key) throws ioexcept关于父亲节的感恩语ion { socketchannel client = (socketchannel) key.channel(); // 获取发给这个客户端的消息,并清空消息 client.write(chart.encode((string) key.attach(null))); key.interestops(lectionkey.op_read); }}
客户端(包含了socket版本和socketchannel版本):
package client; import java.io.ioexception;import java.net.inetsocketaddress;import java.net.socket;import java.net.unknownhostexception;import java.nio.bytebuffer;import 山怎么形容java.nio.channels.socketchannel;import java.nio.chart.chart;import java.util.scanner; import constant.constant; public class socketclient { public static void main(string[] args) throws ioexception { nioversion(); // ioversion(); } private static void ioversion() throws unknownhostexception, ioexception { system.out.println("客户端"); final socket socket = new socket(); socket.connect(new inetsocketaddress(constant.rverport)); new thread() { @override public void run() { scanner scanner = new scanner(system.in); while (scanner.hasnext()) { string line = scanner.nextline(); try { socket.getoutputstream().write((line + "\n").getbytes("utf-8")); } catch (ioexception e) { e.printstacktrace(); } } scanner.clo(); try { socket.clo(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } }; }.start(); new thread() { @override public void run() { try { scanner scanner = new scanner(socket.getinputstream(), "utf-8"); while (scanner.hasnext()) { string line = scanner.nextline(); system.out.println("收到消息:" + line); } scanner.clo(); } catch (ioexception e) { e.printstacktrace(); } } }.start(); } private static void nioversion() throws ioexception { chart chart = chart.forname("utf-8"); system.out.println("客户端"); socketchannel socketchannel = socketchannel.open(); // 设置为非阻塞模式 socketchannel.configureblocking(fal); socketchannel.connect(new inetsocketaddress(constant.rverport)); while (true) { if (s股的意思ocketchannel.finishconnect()) { new thread() { @override public void run() { scanner scanner = new scanner(system.in); while (scanner.hasnext()) { string input = scanner.nextline(); try { socketchannel.write(chart.encode(input)); } catch (ioexception e) { e.printstacktrace(); } } scanner.clo(); } }.start(); new thread() { bytebuffer dst = bytebuffer.allocate(1024); 沉思的近义词 @override public void run() { while (true) { try { int len = socketchannel.read(dst); if (len > 0) { dst.flip(); system.out.println("收到消息:" + chart.decode(dst)); dst.compact(); } } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } } }.start(); return; } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。
本文发布于:2023-04-03 22:37:59,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/2151024f12e5d155febf78befe9de5ae.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Java NIO实现聊天室功能.doc
本文 PDF 下载地址:Java NIO实现聊天室功能.pdf
留言与评论(共有 0 条评论) |