基于Nio的echo server和echo client
程序员文章站
2022-07-10 15:10:21
...
最近想学netty,但平常工作中NIO用的比较少,所以最近就复习了下NIO。自己写了个基于NIO的echo例子,代码挺简单的。
echo 服务端代码
echo 客户端代码
启动测试的代码
echo 服务端代码
package study.nio.echo; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EchoServer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(EchoServer.class); private Selector selector; private ServerSocketChannel serverSocketChannel; private ByteBuffer byteBuffer = ByteBuffer.allocate(1024); public EchoServer(int port) { try { selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.bind(new InetSocketAddress(port)); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { LOGGER.error(e.getMessage()); System.exit(0); } } @Override public void run() { if (selector.isOpen() == false) { LOGGER.warn("echo server selector is not start"); return; } LOGGER.warn("echo server started"); while (true) { try { selector.select(); Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keysIter = selectedKeys.iterator(); while (keysIter.hasNext()) { SelectionKey key = keysIter.next(); keysIter.remove(); if (key.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); LOGGER.info("echo server is connected"); sc.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel sc = (SocketChannel) key.channel(); StringBuilder strb = new StringBuilder(1024); while (sc.read(byteBuffer) > 0) { byteBuffer.flip(); byte[] bytes = new byte[byteBuffer.remaining()]; byteBuffer.get(bytes); byteBuffer.clear(); String msg = new String(bytes); LOGGER.info("echo server read msg:" + msg); strb.append(msg); } ByteBuffer writeBuffer = ByteBuffer.wrap(strb.toString().getBytes()); LOGGER.info("{}", writeBuffer.position()); LOGGER.info("{}", writeBuffer.limit()); sc.write(writeBuffer); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
echo 客户端代码
package study.nio.echo; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EchoClient implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(EchoClient.class); private Selector selector; private SocketChannel socketChannel; private ByteBuffer byteBuffer; public EchoClient(String ip, int port) { try { selector = Selector.open(); socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(ip, port)); socketChannel.register(selector, SelectionKey.OP_CONNECT); } catch (IOException e) { LOGGER.error(e.getMessage()); System.exit(0); } } @Override public void run() { if (selector.isOpen() == false) { LOGGER.warn("echo client selector is not start"); return; } LOGGER.warn("echo client started"); while (true) { try { if (selector.isOpen() == false) { LOGGER.warn("selector is closed"); break; } selector.select(); Iterator<SelectionKey> ite = this.selector.selectedKeys().iterator(); while (ite.hasNext()) { SelectionKey key = (SelectionKey) ite.next(); ite.remove(); if (key.isConnectable()) { SocketChannel channel = (SocketChannel) key.channel(); // 如果正在连接,则完成连接 if (channel.isConnectionPending()) { channel.finishConnect(); } LOGGER.info("echo client is connected"); // 设置成非阻塞 channel.configureBlocking(false); channel.write(ByteBuffer.wrap("this echo client msg,over".getBytes())); channel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel sc = (SocketChannel) key.channel(); StringBuilder strb = new StringBuilder(1024); while (sc.read(byteBuffer) > 0) { byteBuffer.flip(); byte[] bytes = new byte[byteBuffer.remaining()]; byteBuffer.get(bytes); byteBuffer.clear(); String msg = new String(bytes); strb.append(msg); } LOGGER.info("echo client read msg:" + strb.toString()); break; } } } catch (IOException e) { LOGGER.error(e.getMessage()); System.exit(0); } } } }
启动测试的代码
package study.nio.echo; public class EchoTest1 { public static void main(String[] args) { EchoClient echoClient = new EchoClient("127.0.0.1", EchoTest.serverPort); echoClient.run(); } }
package study.nio.echo; public class EchoTest1 { public static void main(String[] args) { EchoClient echoClient = new EchoClient("127.0.0.1", EchoTest.serverPort); echoClient.run(); } }
上一篇: 游标简单操作