Java NIO实现聊天功能

网友投稿 218 2022-09-13


Java NIO实现聊天功能

本文实例为大家分享了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 selectionKeys = null;

private Iterator iterator = null;

private Iterator 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 clients = new ArrayList();

//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 selectionKeys = null;

Iterator 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 clientSessionList = new ArrayList();

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

LPSqn 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 TextLinhttp://eCodecFactory(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.


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:第八期拓扑-三层交换机作为中继器服务器作为DHCP【思科】(思科三层交换机配置dhcp中继)
下一篇:RIP(ripper)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~