NIO实现群聊
NIO实现服务端
public class NIOServer {
private static final int PORT = 6666;
private Selector selector;
private ServerSocketChannel serverSocketChannel;
public static void main(String[] args) throws IOException {
new NIOServer().listen();
}
public NIOServer() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
}
}
public void listen() {
try {
while(true) {
if(selector.select()>0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while(iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if(selectionKey.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
String clientName = socketChannel.getRemoteAddress().toString().substring(1);
System.out.println("clent:"+clientName+"上线");
}
if(selectionKey.isReadable()) {
recvData(selectionKey);
}
iterator.remove();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void recvData(SelectionKey selectionKey) throws IOException {
SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int read = socketChannel.read(byteBuffer);
if(read == -1) {
System.out.println("read:"+read);
socketChannel.close();
}
String msg = new String(byteBuffer.array());
sendToClient(socketChannel, msg);
}
public void sendToClient(SocketChannel self,String msg) throws IOException {
String clientName = self.getRemoteAddress().toString().substring(1);
msg = clientName+" :"+msg;
Iterator<SelectionKey> iterator = selector.keys().iterator();
while(iterator.hasNext()) {
SelectableChannel channel = iterator.next().channel();
if(channel instanceof SocketChannel && self != channel) {
((SocketChannel)(channel)).write(ByteBuffer.wrap(msg.getBytes()));
}
}
}
}
NIO实现客户端
public class NIOClient {
private static final String HOSTNAME = "127.0.0.1";
private static final int PORT = 6666;
private Selector selector;
private SocketChannel socketChannel;
public static void main(String[] args) {
new NIOClient().recvData();
}
public NIOClient() {
try {
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.socket().connect(new InetSocketAddress(HOSTNAME, PORT));
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} catch (IOException e) {
e.printStackTrace();
}
}
public void recvData() {
try {
String client = socketChannel.getLocalAddress().toString().substring(1);
System.out.println(client);
SendData data = new SendData();
new Thread(data).start();
while(true) {
if(selector.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);
}
iterator.remove();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
class SendData implements Runnable{
private Scanner scanner = new Scanner(System.in);
@Override
public void run() {
sendMsg();
}
public void sendMsg() {
try {
while(true) {
String msg = scanner.nextLine();
System.out.println("我:"+msg);
socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意事项
- socketChannel.configureBlocking(false); 需要设置成false
- iterator.remove(); 需要移除,不然重复执行