实例要求:
public class GroupChatServer {
//定义属性
private final int PORT = 9999;
private Selector selector;
private ServerSocketChannel listenChannel;
//构造方法,初始化属性
private GroupChatServer() throws IOException {
selector = Selector.open();
listenChannel = ServerSocketChannel.open();
//绑定端口
listenChannel.socket().bind(new InetSocketAddress(PORT));
//设置非堵塞
listenChannel.configureBlocking(false);
//将listenChannel注册到Selector上
listenChannel.register(selector, SelectionKey.OP_ACCEPT);
}
private void listen() throws IOException {
System.out.println("监听线程=" + Thread.currentThread().getName());
//循环监听
while (true) {
//查询是否有事件
int count = selector.select();
if (count > 0) {
//遍历得到selectionKey 集合
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
//监听到accept
if (key.isAcceptable()) {
SocketChannel sc = listenChannel.accept();
sc.configureBlocking(false);
//将该 sc 注册到selector
sc.register(selector, SelectionKey.OP_READ);
//提示
System.out.println(sc.socket().getRemoteSocketAddress() + " 上线 ");
}
if (key.isReadable()) {
//通道发送read事件,即通道是可读的状态
//处理读 (专门写方法..)
readData(key);
}
//当前的key 删除,防止重复处理
iterator.remove();
}
} else {
System.out.println(" 等待 ");
}
}
}
private void readData(SelectionKey key) {
//获取关联的SocketChannel
SocketChannel channel = null;
try {
channel = (SocketChannel) key.channel();
//设置缓存
ByteBuffer buffer = ByteBuffer.allocate(1024);
int count = channel.read(buffer);
if (count > 0) {
//把缓存区的数据转换为字符串
String msg = new String(buffer.array());
//输出该消息
System.out.println("form 客户端: " + msg);
//向其它的客户端转发消息(去掉自己)
sendMsgToOtherClients(msg, channel);
}
} catch (IOException e) {
try {
System.out.println(channel.socket().getRemoteSocketAddress() + " 离线了..");
//取消注册
key.cancel();
//关闭通道
channel.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
private void sendMsgToOtherClients(String msg, SocketChannel clientSelf) throws IOException {
System.out.println("服务器转发数据给客户端线程: " + Thread.currentThread().getName());
Set<SelectionKey> keys = selector.keys();
for (SelectionKey key : keys) {
Channel toChannel = key.channel();
//排除自己
if (toChannel instanceof SocketChannel && toChannel != clientSelf) {
SocketChannel other = (SocketChannel) toChannel;
//把消息转成ByteBuffer
ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
//ByteBuffer写道通道里
other.write(buffer);
}
}
}
public static void main(String[] args) throws IOException {
GroupChatServer server = new GroupChatServer();
server.listen();
}
}
public class GroupChatClient {
//定义属性
private final String HOST = "127.0.0.1";
private final int PORT = 9999;
private Selector selector;
private SocketChannel socketChannel;
private String username;
//构造器, 完成初始化工作
public GroupChatClient() throws IOException {
selector = Selector.open();
//连接服务器
socketChannel = socketChannel.open(new InetSocketAddress(HOST, PORT));
//设置非阻塞
socketChannel.configureBlocking(false);
//将channel 注册到selector
socketChannel.register(selector, SelectionKey.OP_READ);
//得到username
username = socketChannel.getLocalAddress().toString().substring(1);
System.out.println(username + " is ok...");
}
private void sendMsg(String msg) throws IOException {
msg = username + " 说 " + msg;
socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
}
private void readMsg() throws IOException {
//可用通道
int count = selector.select();
if (count > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
sc.read(buffer);
//把buffer转成字符串
System.out.println(new String(buffer.array()));
}
}
iterator.remove();
}
}
public static void main(String[] args) throws IOException {
final GroupChatClient client = new GroupChatClient();
new Thread() {
@Override
public void run() {
while (true) {
try {
client.readMsg();
Thread.currentThread().sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
//发送数据给服务器端
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
client.sendMsg(s);
}
}
}