java nio 即时通讯_NIO即时通讯/聊天室DEMO

一、服务端

package com.nio;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SelectableChannel;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Iterator;

public class ChatServer {

private ServerSocketChannel listenChannel; //监听通道

private Selector selector; //选择器对象

private static final int PORT = 9999;

public ChatServer() {

try {

// 1得到监听通道

listenChannel = ServerSocketChannel.open();

// 2得到选择器

selector = Selector.open();

// 3绑定端口

listenChannel.bind(new InetSocketAddress(PORT));

// 4设置为非阻塞模式

listenChannel.configureBlocking(false);

// 5将选择器绑定到监听通道并监听accept事件

listenChannel.register(selector, SelectionKey.OP_ACCEPT);

printInfo("server ok ...");

} catch (Exception e) {

e.printStackTrace();

}

}

// 6干活

public void start() {

try {

while (true) {

if (selector.select(3000) == 0) {

continue;

}

Iterator iterator = selector.selectedKeys().iterator();

while(iterator.hasNext()) {

SelectionKey key = iterator.next();

if (key.isAcceptable()) { // 连接请求事件

SocketChannel sc = listenChannel.accept();

sc.configureBlocking(false);

sc.register(selector, SelectionKey.OP_READ);

System.out.println(sc.getRemoteAddress().toString().substring(1) + "上线了...");

}

if (key.isReadable()) { // 读取数据事件

readMsg(key);

}

// 把keys删掉,防止重复处理

iterator.remove();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

// 读取到客户端发送过来的消息并广播出去

public void readMsg(SelectionKey key) throws Exception {

SocketChannel sc = (SocketChannel) key.channel();

ByteBuffer buffer = ByteBuffer.allocate(1024);

if (sc.read(buffer) > 0) {

// 打印接收到的消息

String msg = new String(buffer.array());

printInfo(msg.trim());

// 发广播

broadCast(sc, msg);

}

}

public void broadCast(SocketChannel sc, String msg) throws Exception {

printInfo("服务器发送了广播...");

for (SelectionKey key : selector.keys()) {

SelectableChannel channel;

if ((channel = key.channel()) instanceof SocketChannel && key.channel() != sc) {

ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());

((SocketChannel) channel).write(buffer);

}

}

}

private void printInfo(String str) {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println("["+sdf.format(new Date()) + "]->" + str);

}

public static void main(String[] args) {

new ChatServer().start();

}

}

二、客户端

package com.nio;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SocketChannel;

public class ChatClient {

private final String HOST = "127.0.0.1";

private int PORT = 9999;

private SocketChannel socketChannel;

private String userName;

public ChatClient() {

try {

// 1得到一个网络通道

socketChannel = SocketChannel.open();

// 2设置非阻塞方式

socketChannel.configureBlocking(false);

// 3服务端IP和端口

InetSocketAddress inetSocketAddress = new InetSocketAddress(HOST, PORT);

// 4连接服务器

if (!socketChannel.connect(inetSocketAddress)) {

while (!socketChannel.finishConnect()) {

System.out.println("客户端一直在连接.....");

}

}

// 5得到客户端IP和端口,作为聊天用户名

userName = socketChannel.getLocalAddress().toString().substring(1);

System.out.println("-------------client: " + userName + " is ready-------------");

} catch (Exception e) {

e.printStackTrace();

}

}

// 向服务器发送数据

public void sendMsg(String msg) throws Exception {

if (msg.equalsIgnoreCase("bye")) {

socketChannel.close();

return;

}

msg = userName + "say: " + msg;

ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());

socketChannel.write(buffer);

}

// 从服务端接收数据

public void receiveMsg() throws Exception {

ByteBuffer buffer = ByteBuffer.allocate(1024);

if (socketChannel.read(buffer) > 0) {

String msg = new String(buffer.array());

System.out.println(msg.trim());

}

}

}

三、测试客户端,启多个线程

package com.nio;

import java.util.Scanner;

public class Test {

public static void main(String[] args) throws Exception {

ChatClient chatClient = new ChatClient();

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

try {

chatClient.receiveMsg();

Thread.sleep(3000);

} catch (Exception e) {

e.printStackTrace();

}

}

}

}).start();

Scanner scanner = new Scanner(System.in);

while(scanner.hasNextLine()) {

chatClient.sendMsg(scanner.nextLine());

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值