1. NIO完成一个TCP聊天室
1.1 NIO TCP聊天室客户端完成
package com.qfedu.b_niochat;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class ChatClient {
private static final String HOST = "192.168.31.154";
private static final int PORT = 8848;
private SocketChannel socket;
private String userName;
public ChatClient(String userName) throws IOException, InterruptedException {
socket = SocketChannel.open();
socket.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress(HOST, PORT);
if (!socket.connect(address)) {
while (!socket.finishConnect()) {
System.out.println("服务器请求连接失败,等待2s继续请求连接...");
Thread.sleep(2000);
}
}
this.userName = userName;
System.out.println("客户端 " + userName + " 准备就绪");
}
public void sendMsg(String message) throws IOException {
if ("close".equals(message)) {
socket.close();
return;
}
message = userName + ":" + message;
ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
socket.write(buffer);
}
public void receiveMsg() throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = socket.read(buffer);
if (length > 0) {
System.out.println(new String(buffer.array()));
}
}
}
1.2 NIO TCP聊天室服务端完成
package com.qfedu.b_niochat;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
public class ChatServer {
private ServerSocketChannel serverSocket;
private Selector selector;
private static final int PORT = 8848;
public ChatServer() throws IOException {
serverSocket = ServerSocketChannel.open();
selector = Selector.open();
serverSocket.bind(new InetSocketAddress(PORT));
serverSocket.configureBlocking(false);
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
}
public void start(){
try {
while (true) {
if (0 == selector.select(2000)) {
System.out.println("服务器默默的等待连接,无人访问...");
continue;
}
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
SocketChannel socket = serverSocket.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ);
broadcast(socket, socket.getRemoteAddress().toString() + "上线了");
}
if (key.isReadable()) {
readMsg(key);
}
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void readMsg(SelectionKey key) throws IOException {
SocketChannel socket = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = socket.read(buffer);
if (length > 0) {
String message = new String(buffer.array());
broadcast(socket, message);
}
}
public void broadcast(SocketChannel self, String message) throws IOException {
Set<SelectionKey> keys = selector.keys();
for (SelectionKey key : keys) {
SelectableChannel channel = key.channel();
if (channel instanceof SocketChannel && !channel.equals(self)) {
SocketChannel socketChannel = (SocketChannel) channel;
ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
socketChannel.write(buffer);
}
}
}
public static void main(String[] args) throws IOException {
new ChatServer().start();
}
}
1.3 NIO TCP聊天室客户端线程代码实现
package com.qfedu.b_niochat;
import java.io.IOException;
import java.util.Scanner;
public class ChatClientThread {
public static void main(String[] args) throws IOException, InterruptedException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = scanner.nextLine();
if (0 == userName.length()) {
return;
}
ChatClient chatClient = new ChatClient(userName);
new Thread(() -> {
while (true) {
try {
chatClient.receiveMsg();
Thread.sleep(2000);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}).start();
while (scanner.hasNextLine()) {
String msg = scanner.nextLine();
chatClient.sendMsg(msg);
}
}
}