软件编程
位置:首页>> 软件编程>> java编程>> Java NIO实现聊天功能

Java NIO实现聊天功能

作者:TCH987551623  发布时间:2022-06-12 08:31:31 

标签: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<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.

来源:https://blog.csdn.net/TCH987551623/article/details/84611450

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com