Internet chat rooms to achieve NIO
1. Selector
Before entering the code, we first look at selectors: Selector, network programming of cellular phones, server may execute one thread running Selector program, listening to operate. Its role is to check the status of one or more channels readable.
Selector commonly used methods:
- public static Selector Open ();
to give a selected object - public int select (long timeout);
listen to all channels registered, if the present operation IO streams, will SelectionKey information corresponding to the set of stored inside, the parameter is a timeout - public Set selectionKeys ();
Returns the current save Selector internal collection of all SelectionKey
1.1 SelectionKey
SelectionKey represents SelectionKey network channel and direct relationship
int OP_ACCEPT; 16 needs to be connected
int OP_CONNECT; 8 connected
Int OP_WRITE; 4 writes
int OP_READ; 1 read operation
method:
- public abstract Selector selector ();
obtained Selector object associated therewith - public abstract SelectableChannel channel ();
resulting associated channel - public final Object attachment ();
obtained shared data associated therewith - public abstract SelectionKey interestOps (int ops) ;
to set or change the monitor events - public final boolean isAcceptable ();
Can accept - public final boolean isReadable ();
Can read - public final boolean isWritable ();
if you can write
1.2 ServerSocketChannel
Socket server program corresponding to the Channel
method | effect |
---|---|
public static ServerSocketChannel open() | Turn on the server ServerSocketChannel channel |
public final ServerSocketChannel bind(SocketAddress local); | Set server port number |
public final SelectableChannel configureBlocking(boolean block); | Set blocking or non-blocking mode, false representation non-blocking |
public SocketChannel accept() | Acquiring a client connection, and the operation to obtain the corresponding channel |
public final SelectionKey register(Selector sel, int ops) | Register selector, and choose what event monitor |
1.3 SocketChannel
Socket client objects corresponding to Channel
method | effect |
---|---|
static SocketChannel open() | Open a client Socket Channel object |
final SelectableChannel configureBlocking(boolean block) | Settings are blocked or unblocked |
boolean connect(SocketAddress remote) | connect to the server |
boolean finishConnect() | If you connect the connection fails, you can continue to connect through finishConnect |
final SelectionKey register(Selector sel, int ops, Object attechment); | Register the SocketChannel, select a corresponding listening operation, and may have parameters Object attachment |
final void close() | Close SocketChannel |
2. NIO complete a client and server
2.1 server part
public static void main(String[] args) throws IOException {
// 1. 开启服务器
ServerSocketChannel serverSocket = ServerSocketChannel.open();
// 2. 开启Selector
Selector selector = Selector.open();
// 3. 服务端代码绑定端口号
serverSocket.bind(new InetSocketAddress(8848));
// 4. 设置非阻塞状态
serverSocket.configureBlocking(false);
//5. ServerSocketChannel 注册--> Selector 返回值是一个SelectionKey
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
if (0 == selector.select(1000)) {
// 0 == selector.select(1000) 表示没有连接到客户端
continue;
}
Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
while (selectionKeys.hasNext()) {
SelectionKey selectionKey = selectionKeys.next();
//连接请求
if (selectionKey.isAcceptable()) {
System.out.println("客户端请求连接!!!");
SocketChannel socket = serverSocket.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024 * 4));
}
//可读
if (selectionKey.isReadable()) {
SocketChannel socket = (SocketChannel) selectionKey.channel();
ByteBuffer buffer = (ByteBuffer) selectionKey.attachment();
socket.read(buffer);
System.out.println("客户端发送数据:" + new String(buffer.array()));
}
selectionKeys.remove();
}
}
}
2.2 The client part
//main方法内
SocketChannel socket = SocketChannel.open();
socket.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress("192.168.1.110", 8848);
//l连接服务器
if (!socket.connect(address)) {
while (!socket.finishConnect()) {
System.out.println("保持呼叫服务器状态,但是我还能做点别的事情~~~ 等待2s继续申请连接~~~");
Thread.sleep(2000);
}
}
//准备一个数据存入到缓冲区
ByteBuffer buffer = ByteBuffer.wrap("你好,服务器,我在等你...".getBytes());
socket.write(buffer);
new Scanner(System.in).nextLine();