Client
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
.nio
.charset
.Charset
;
import java
.util
.Iterator
;
import java
.util
.Scanner
;
import java
.util
.Set
;
public class ClientNio {
private Selector selector
= null
;
static final int port
= 8082;
private Charset charset
= Charset
.forName("UTF-8");
private SocketChannel sc
= null
;
private String name
= "";
private static String USER_EXIST
= "system message: user exist, please change a name";
private static String USER_CONTENT_SPILIT
= "#@#";
public void init() throws IOException
{
name
= System
.currentTimeMillis()+ "";
System
.out
.println("user name === " + name
);
selector
= Selector
.open();
sc
= SocketChannel
.open(new InetSocketAddress("127.0.0.1", port
));
sc
.configureBlocking(false);
sc
.register(selector
, SelectionKey
.OP_READ
);
new Thread(new ClientThread()).start();
Scanner scan
= new Scanner(System
.in
);
sc
.write(charset
.encode(name
));
while (scan
.hasNextLine()) {
String line
= scan
.nextLine();
if ("".equals(line
)) continue;
if ("".equals(name
)) {
name
= line
;
line
= name
+ USER_CONTENT_SPILIT
;
} else {
line
= name
+ USER_CONTENT_SPILIT
+ line
;
}
sc
.write(charset
.encode(line
));
}
}
private class ClientThread implements Runnable {
public void run() {
try {
while (true) {
int readyChannels
= selector
.select();
if (readyChannels
== 0) continue;
Set selectedKeys
= selector
.selectedKeys();
Iterator keyIterator
= selectedKeys
.iterator();
while (keyIterator
.hasNext()) {
SelectionKey sk
= (SelectionKey
) keyIterator
.next();
keyIterator
.remove();
dealWithSelectionKey(sk
);
}
}
} catch (IOException io
) {
}
}
private void dealWithSelectionKey(SelectionKey sk
) throws IOException
{
if (sk
.isReadable()) {
SocketChannel sc
= (SocketChannel
) sk
.channel();
ByteBuffer buff
= ByteBuffer
.allocate(1024);
String content
= "";
while (sc
.read(buff
) > 0) {
buff
.flip();
content
+= charset
.decode(buff
);
}
if (USER_EXIST
.equals(content
)) {
name
= "";
}
System
.out
.println(content
);
sk
.interestOps(SelectionKey
.OP_READ
);
}
}
}
public static void main(String
[] args
) throws IOException
{
new ClientNio().init();
}
}
Server
import java
.io
.IOException
;
import java
.net
.InetSocketAddress
;
import java
.nio
.ByteBuffer
;
import java
.nio
.channels
.*
;
import java
.nio
.charset
.Charset
;
import java
.util
.ArrayList
;
import java
.util
.Iterator
;
import java
.util
.List
;
import java
.util
.Set
;
public class ServerNio {
private Selector selector
= null
;
static final int port
= 8082;
private Charset charset
= Charset
.forName("UTF-8");
private static List
<String> users
= new ArrayList<String>();
private static String USER_EXIST
= "system message: user exist, please change a name";
private static String USER_CONTENT_SPILIT
= "#@#";
private static boolean flag
= false;
public void init() throws IOException
{
selector
= Selector
.open();
ServerSocketChannel server
= ServerSocketChannel
.open();
server
.bind(new InetSocketAddress(port
));
server
.configureBlocking(false);
server
.register(selector
, SelectionKey
.OP_ACCEPT
);
System
.out
.println("Server is listening now...");
while (true) {
int readyChannels
= selector
.select();
if (readyChannels
== 0) continue;
Set selectedKeys
= selector
.selectedKeys();
Iterator keyIterator
= selectedKeys
.iterator();
while (keyIterator
.hasNext()) {
SelectionKey sk
= (SelectionKey
) keyIterator
.next();
keyIterator
.remove();
dealWithSelectionKey(server
, sk
);
}
}
}
public void dealWithSelectionKey(ServerSocketChannel server
, SelectionKey sk
) throws IOException
{
if (sk
.isAcceptable()) {
SocketChannel sc
= server
.accept();
sc
.configureBlocking(false);
sc
.register(selector
, SelectionKey
.OP_READ
);
sk
.interestOps(SelectionKey
.OP_ACCEPT
);
sc
.write(charset
.encode("Please input your name."));
}
if (sk
.isReadable()) {
SocketChannel sc
= (SocketChannel
) sk
.channel();
ByteBuffer buff
= ByteBuffer
.allocate(1024);
StringBuilder content
= new StringBuilder();
try {
while (sc
.read(buff
) > 0) {
buff
.flip();
content
.append(charset
.decode(buff
));
}
sk
.interestOps(SelectionKey
.OP_READ
);
} catch (IOException io
) {
sk
.cancel();
if (sk
.channel() != null
) {
sk
.channel().close();
}
}
if (content
.length() > 0) {
String
[] arrayContent
= content
.toString().split(USER_CONTENT_SPILIT
);
if (arrayContent
.length
== 1) {
String name
= arrayContent
[0];
users
.add(name
);
int num
= onlineNum(selector
);
String message
= "welcome " + name
+ " to chat room! Online numbers:" + num
;
System
.out
.println(message
);
broadCast(selector
, null
, message
);
}
else if ( arrayContent
.length
> 1) {
String name
= arrayContent
[0];
String message
= content
.substring(name
.length() + USER_CONTENT_SPILIT
.length());
message
= arrayContent
[1];
message
= name
+ " say " + message
;
String message1
= "get message: " + message
;
System
.out
.println(message1
);
if (users
.contains(name
)) {
broadCast(selector
, sc
, message
);
}
}
}
}
}
public static int onlineNum(Selector selector
) {
int res
= 0;
for (SelectionKey key
: selector
.keys()) {
Channel targetchannel
= key
.channel();
if (targetchannel
instanceof SocketChannel) {
res
++;
}
}
return res
;
}
public void broadCast(Selector selector
, SocketChannel except
, String content
) throws IOException
{
for (SelectionKey key
: selector
.keys()) {
Channel targetchannel
= key
.channel();
if (targetchannel
instanceof SocketChannel && targetchannel
!= except
) {
SocketChannel dest
= (SocketChannel
) targetchannel
;
dest
.write(charset
.encode(content
));
}
}
}
public static void main(String
[] args
) throws IOException
{
new ServerNio().init();
}
}
github源码:https://github.com/weiyang00/chat-rooms/tree/master/java-chat-room/src/main/java/example/nio