NIO编写的和客户端和服务端示例
服务端:
package com.nettyStudy.nio.groupChat;
import org.omg.Messaging.SyncScopeHelper;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class GroupChatServer {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private static final int port = 5555;
public GroupChatServer(){
try{
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}catch (Exception e){
e.printStackTrace();
}
}
private void listen(){
try {
while (true){
int count = selector.select(2000);
if(count > 0){
Iterator<SelectionKey> sks = selector.selectedKeys().iterator();
while (sks.hasNext()){
SelectionKey selectionKey = sks.next();
//监听到客户端accept事件,客户端连接上线
if (selectionKey.isAcceptable()){
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ);
System.out.println(socketChannel.getRemoteAddress() + " 上线");
}
//通道发送读事件,为可读状态,读取客户端数据
if(selectionKey.isReadable()){
readMsg(selectionKey);
}
sks.remove();
}
}else {
//System.out.println("等待...");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
private void readMsg(SelectionKey selectionKey){
SocketChannel socketChannel = null;
try {
socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int read = socketChannel.read(byteBuffer);
if(read > 0){
String msg = new String(byteBuffer.array());
System.out.println("收到客户端"+socketChannel.getRemoteAddress() + "消息:"+msg);
//向其他客户端转发消息
redirectMsg(msg,socketChannel);
}
}catch (Exception e){
//离线了,断开
try {
System.out.println("客户端"+socketChannel.getRemoteAddress() + "离线了");
selectionKey.cancel();
socketChannel.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private void redirectMsg(String msg,SocketChannel self) throws IOException {
System.out.println("服务器转发消息:form:"+ self.getRemoteAddress() + ", msg:"+msg);
for(SelectionKey key: selector.keys()){
Channel targetChannel = key.channel();
if(targetChannel instanceof SocketChannel && targetChannel != self){
//发送消息到客户端
((SocketChannel) targetChannel).write(ByteBuffer.wrap(msg.getBytes()));
}
}
}
public static void main(String[] args) {
new GroupChatServer().listen();
}
}
客户端:
package com.nettyStudy.nio.groupChat;
import java.io.IOException;
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.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
public class GroupChatClient {
public static void main(String[] args) throws Exception {
//启动我们客户端
GroupChatClient chatClient = new GroupChatClient();
//启动一个线程, 每个3秒,读取从服务器发送数据
new Thread() {
public void run() {
while (true) {
chatClient.readInfo();
try {
Thread.currentThread().sleep(3000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
//发送数据给服务器端
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
chatClient.sendInfo(s);
}
}
private Selector selector;
private SocketChannel socketChannel;
private String userName;
public GroupChatClient(){
try {
selector = Selector.open();
socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",5555));
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ);
userName = socketChannel.getLocalAddress().toString();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendInfo(String info){
info = userName + " 说:" + info;
try {
socketChannel.write(ByteBuffer.wrap(info.getBytes()));
}catch (IOException e){
e.printStackTrace();
}
}
private void readInfo(){
try {
int select = selector.select(1000);
if(select > 0){
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()){
SelectionKey selectionKey = iterator.next();
if(selectionKey.isReadable()){
SocketChannel channel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
channel.read(byteBuffer);
String msg = new String(byteBuffer.array());
System.out.println(msg.trim());
}
}
iterator.remove();
}else{
//System.out.println("客户端没有可以用的通道");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}