1、NIOChatServer
public class NIOChatServer {
private int port = 8080;
private Charset charset = Charset.forName("UTF-8");
private static HashSet<String> users = new HashSet<String>();
private static String USER_EXIST = "系统提示:该昵称已经存在,请换一个昵称";
private static String USER_CONTENT_SPILIT = "#@#";
private Selector selector = null;
public NIOChatServer(int port) throws IOException{
this.port = port;
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(this.port));
server.configureBlocking(false);
selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务已启动,监听端口是:" + this.port);
}
public void listen() throws IOException{
while(true) {
int wait = selector.select();
if(wait == 0) continue;
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while(iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
process(key);
}
}
}
public void process(SelectionKey key) throws IOException {
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel)key.channel();
SocketChannel client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
key.interestOps(SelectionKey.OP_ACCEPT);
client.write(charset.encode("请输入你的昵称"));
}
if(key.isReadable()){
SocketChannel client = (SocketChannel)key.channel();
ByteBuffer buff = ByteBuffer.allocate(1024);
StringBuilder content = new StringBuilder();
try{
while(client.read(buff) > 0) {
buff.flip();
content.append(charset.decode(buff));
}
key.interestOps(SelectionKey.OP_READ);
}catch (IOException io){
key.cancel();
if(key.channel() != null) {
key.channel().close();
}
}
if(content.length() > 0) {
String[] arrayContent = content.toString().split(USER_CONTENT_SPILIT);
if(arrayContent != null && arrayContent.length == 1) {
String nickName = arrayContent[0];
if(users.contains(nickName)) {
client.write(charset.encode(USER_EXIST));
} else {
users.add(nickName);
int onlineCount = onlineCount();
String message = "欢迎 " + nickName + " 进入聊天室! 当前在线人数:" + onlineCount;
broadCast(null, message);
}
}
else if(arrayContent != null && arrayContent.length > 1) {
String nickName = arrayContent[0];
String message = content.substring(nickName.length() + USER_CONTENT_SPILIT.length());
message = nickName + " 说 " + message;
if(users.contains(nickName)) {
broadCast(client, message);
}
}
}
}
}
public int onlineCount() {
int res = 0;
for(SelectionKey key : selector.keys()){
Channel target = key.channel();
if(target instanceof SocketChannel){
res++;
}
}
return res;
}
public void broadCast(SocketChannel client, String content) throws IOException {
for(SelectionKey key : selector.keys()) {
Channel targetchannel = key.channel();
if(targetchannel instanceof SocketChannel && targetchannel != client) {
SocketChannel target = (SocketChannel)targetchannel;
target.write(charset.encode(content));
}
}
}
public static void main(String[] args) throws IOException {
new NIOChatServer(8080).listen();
}
}
2、NIOChatClient
public class NIOChatClient {
private final InetSocketAddress serverAdrress = new InetSocketAddress("localhost", 8080);
private Selector selector = null;
private SocketChannel client = null;
private String nickName = "";
private Charset charset = Charset.forName("UTF-8");
private static String USER_EXIST = "系统提示:该昵称已经存在,请换一个昵称";
private static String USER_CONTENT_SPILIT = "#@#";
public NIOChatClient() throws IOException{
selector = Selector.open();
client = SocketChannel.open(serverAdrress);
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
public void session(){
new Reader().start();
new Writer().start();
}
private class Writer extends Thread{
@Override
public void run() {
try{
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine()){
String line = scan.nextLine();
if("".equals(line)) continue;
if("".equals(nickName)) {
nickName = line;
line = nickName + USER_CONTENT_SPILIT;
} else {
line = nickName + USER_CONTENT_SPILIT + line;
}
client.write(charset.encode(line));
}
scan.close();
}catch(Exception e){
}
}
}
private class Reader extends Thread {
public void run() {
try {
while(true) {
int readyChannels = selector.select();
if(readyChannels == 0) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey key = (SelectionKey) keyIterator.next();
keyIterator.remove();
process(key);
}
}
}
catch (IOException io){
}
}
private void process(SelectionKey key) throws IOException {
if(key.isReadable()){
SocketChannel sc = (SocketChannel)key.channel();
ByteBuffer buff = ByteBuffer.allocate(1024);
String content = "";
while(sc.read(buff) > 0)
{
buff.flip();
content += charset.decode(buff);
}
if(USER_EXIST.equals(content)) {
nickName = "";
}
System.out.println(content);
key.interestOps(SelectionKey.OP_READ);
}
}
}
public static void main(String[] args) throws IOException {
new NIOChatClient().session();
}
}