通過NIO的學習,自己簡單寫了一個,C/S架構的聊天工具。
Server端:
1.接受客戶端Channel。
2.記錄客戶端集合clients。利用channel進行區分客戶端,後續可以添加一個ID。
3.客戶端通過遍歷clients,對除發送者以外的所有客戶端通訊。
Client端:
1.發送請求。
2.接收內容
3.獲取控制檯內容,併發送
待解決問題:
由於獲取控制檯數據的流,System.in是阻塞的IO:
ReadableByteChannel in=Channels.newChannel(System.in);
ByteBuffer buffer = ByteBuffer.allocate(1024);
in.read(buffer);//這裏會阻塞
所以每次接收消息的話,並需控制檯觸發一下,不知道有沒有好的方法,還請知道的大牛指導下,謝謝
以下是代碼:
public class NioServer {
private static Set<SocketChannel> clients=new HashSet<SocketChannel>();
public static void main(String[] args) {
ServerSocketChannel serverChannel;
Selector selector;
try{
//服務端的準備
serverChannel= ServerSocketChannel.open();
ServerSocket serverSocket=serverChannel.socket();
serverSocket.bind(new InetSocketAddress(12345));
serverChannel.configureBlocking(false);
selector=Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e){
e.printStackTrace();
return;
}
while(true){
try {
selector.select();
System.out.println("======select========");
} catch (IOException e) {
e.printStackTrace();
break;
}
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while(iterator.hasNext()){
SelectionKey key=iterator.next();
iterator.remove();
try {
if(key.isAcceptable()){
System.out.println("=============accept============");
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel client=server.accept();//接受客戶端的請求
client.configureBlocking(false);//客戶端 服務端 全都設置爲 非阻塞
clients.add(client);
client.register(key.selector(), SelectionKey.OP_READ);
}
if(key.isReadable()){
System.out.println("=============read==============="+clients);
SocketChannel client=(SocketChannel) key.channel();
ByteBuffer buffer=ByteBuffer.allocate(1024);
if(client.read(buffer)>0){
Iterator<SocketChannel> it=clients.iterator();
while(it.hasNext()){
SocketChannel other=it.next();
if(other != client){
buffer.flip();
other.write(buffer);
}
}
}
key.interestOps(SelectionKey.OP_READ);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private String name="A";
public void execute(){
try {
SocketChannel client = SocketChannel.open();
Selector selector = Selector.open();
client.configureBlocking(false);
client.connect(new InetSocketAddress("127.0.0.1", 12345));
//註冊監聽Connect
client.register(selector, SelectionKey.OP_CONNECT,name);
while(true){
int n = selector.select();
if(n==0){
continue;
}
Iterator<SelectionKey> iterator=selector.selectedKeys().iterator();
while(iterator.hasNext()){
SelectionKey key=iterator.next();
iterator.remove();
if(key.isConnectable() && client.finishConnect()){
System.out.println("[client]:連接成功");
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(name.getBytes());
buffer.flip();
client.write(buffer);
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
if(key.isReadable()){
System.out.println("[client]:開始接受");
ByteBuffer buffer = ByteBuffer.allocate(1024);
WritableByteChannel out = Channels.newChannel(System.out);
while(client.read(buffer)>0){
System.out.println("==============");
buffer.flip();
out.write(buffer);
}
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
if(key.isWritable()){
ReadableByteChannel in=Channels.newChannel(System.in);
ByteBuffer buffer = ByteBuffer.allocate(1024);
if(in.read(buffer)>0){
buffer.flip();
SocketChannel channel = (SocketChannel) key.channel();
channel.write(buffer);
buffer.clear();
}
key.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}