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 聊天室源码”项目中,开发者使用了NIO来构建一个聊天室应用,以实现用户之间的实时通信。 1. **Java NIO基础** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的,如SocketChannel、...
在这个“java nio聊天室源码”项目中,我们可以看到如何使用NIO构建一个实时、高效的多人在线聊天应用。 首先,我们要理解Java NIO的基本概念。NIO包括以下关键组件: 1. **通道(Channels)**:通道是数据传输的...
**JAVA NIO 聊天室程序** 在Java编程领域,网络编程是一个重要的部分,而NIO(Non-blocking Input/Output)是Java提供的一种高效、非阻塞的I/O模型,它极大地提升了处理大量并发连接的能力。这个"JAVA NIO 聊天室...
Java NIO实战之聊天室功能详解主要介绍了Java NIO实战之聊天室功能,结合实例形式详细分析了Java NIO聊天室具体的服务端、客户端相关实现方法与操作注意事项。 Java NIO概述 Java NIO(New I/O)是一种Java API,...
服务端程序基于javaNIO,客户端程序基于旧IO,读完<<javaNIO>>后,导入eclipse即可运行,支持多人在线聊天,上下线通知.PS:非GUI程序,毕竟javaSwing用的少,不懂的地方大家可以一起讨论,评论必回!
import java.nio.channels.SocketChannel; import java.util.Iterator; import com.nio.user.ClientUser; import com.nio.user.ClientUserManager; import com.nio.user.UserData; public class NIOClient { ...
Java NIO(Non-blocking Input/Output)是一种在...在设计聊天服务器时,利用NIO可以有效地处理大量并发用户,降低CPU压力,提高系统整体性能。同时,单线程模型简化了并发控制的复杂性,使得程序更易于理解和维护。
01-Java NIO-课程简介.mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 ...
在实际应用中,Java NIO通常用于高性能的服务器编程,例如在开发聊天服务器、Web服务器或游戏服务器时,可以利用其高效的并发处理能力。然而,NIO的API相对复杂,学习曲线较陡峭,需要花费一定时间去理解和实践。...
1. **高并发服务器**:NIO在开发高性能、大并发的服务器时非常有用,例如聊天服务器、游戏服务器等。 2. **文件操作**:NIO提供了高效、灵活的文件读写能力,特别是对于大数据处理,如日志分析、文件复制等。 3. *...
- **实时通信**:NIO适合实时聊天、在线游戏等需要频繁交互且对延迟敏感的应用。 - **高并发**:在处理大量并发连接时,NIO能有效减少线程消耗,提高系统性能。 这个实例中的"Desk"和"DeskAppServer"可能分别代表...
在这个“Java NIO 学习 聊天室程序”项目中,我们将深入探讨NIO如何用于创建一个聊天室程序。这个程序可能包含以下几个关键部分: 1. **服务器端**:服务器端使用NIO的ServerSocketChannel监听客户端连接。当新的...
使用NIO socket不需要多线程来处理多个连接的请求,效率非常高 ...4,修改封装http做成短连接处理,就是一个小型的webserver,或者结合java2D和robot做远程监控 5,封装自己的协议可以做成自己需要的服务器端程序,
- NIO适用于需要处理大量连接的服务器,如聊天应用、在线游戏服务器等。 - 对实时性要求较高的应用,因为NIO的非阻塞特性可以减少等待时间。 总之,这个Java NIO IM实例是一个很好的学习资源,它演示了如何利用...
JAVA NIO有两种解释:一种叫非阻塞IO(Non-blocking I/O),另一种也叫新的IO(New I/O),其实是同一个概念。它是一种同步非阻塞的I/O模型,也是...本例是使用java nio实现的简单聊天系统,界面简单,旨在学习java nio
### Java NIO 系列教程(一):Java NIO 概述 #### 一、引言 Java NIO(New IO)是Java SE 1.4版本引入的一个新的I/O处理框架,它提供了比传统Java IO包更高效的数据处理方式。NIO的核心在于其三大组件:Channels...
Java NIO(Non-blocking Input/Output)是一种在Java中处理I/O操作的新方式,相比于传统的BIO(Blocking I/O),NIO提供了更高效的数据传输能力,尤其适合于高并发、低延迟的网络应用,如聊天服务器。在这个场景下,...
总的来说,"基于nio的简易聊天室"项目综合运用了Java NIO的多种核心特性,通过通道、缓冲区和选择器实现了高效的网络通信,同时结合GUI提供了友好的用户体验。通过这个项目,开发者可以深入理解NIO在实际应用中的...
Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java应用...NIO适用于需要处理大量并发连接的场景,例如聊天服务器、游戏服务器等。理解并掌握Java NIO的这些概念和用法对于提升Java网络编程能力至关重要。