通过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(); } }