1, IO TCP chat program
1. IO introduction
① Server blocking point
server.accept(); When getting sockets
inputStream.read(bytes); When the input stream reads data
pass
② The unified socket is a short connection and can be used as a short connection server. It cannot make a long connection. It belongs to the ask and answer mode. For example, the underlying layer of the old tomcat uses the socket, and the thread will be turned off when it is used up. Therefore, the thread will not be occupied all the time. It supports processing multiple client connections.
- In the case of single thread, only one client (one thread maintains one connection, that is, one socket client connection) thread can be occupied all the time.
- Using thread pool can have multiple client connections, but it is very performance consuming (using this case is the old tomcat principle, but it is released after use)
2. IO implementation network program
① Create two new java projects (one Server side and one client side)
② Code writing
- server side coding
package com.company; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.io.InputStream; import java.net.Socket; public class Main { public static void main(String[] args) throws IOException { //Create the Socket object of the client (seversocket) //ServerSocket (int port) creates a server socket bound to a specified port ServerSocket ss = new ServerSocket(50000); //Socket accept() listens to connect to this socket and accepts it Socket s = ss.accept(); //Get the input stream, read the data, and display the data on the console InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); String data = new String(bys, 0, len); System.out.println("The data are:" + data); //Release resources s.close(); ss.close(); } }
- client side code
package com.company; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class Main { public static void main(String[] args) throws IOException { //Create a Socket object for the client //Socket (InetAddress, int port) creates a stream socket and connects it to the specified port number of the specified IP address // Socket s=new Socket(InetAddress.getByName("192.168.224.1"), 10000); //Socket (String host,int port) creates a stream socket and connects it to the specified port number of the specified host Socket s=new Socket("127.0.0.1", 50000); //Get output stream and write data //OutputStream getOutputStream(); Returns the output stream of this socket OutputStream os=s.getOutputStream(); os.write("hello,tcp".getBytes()); //Release resources s.close(); } }
③ Operation results
2, NIO TCP chat program
1. NIO introduction
① NIO features
NIO single thread model adopts the polling query mode managed by the selector. The selector checks whether the client side generates messages to be processed (client connection request, client sending data request, client downloading data request) every once in a while, that is, the selector will manage the client side connection and the client side read and write requests in the channel at the same time.
NIO single thread model: using the polling query mode managed by the selector, the selector checks whether the client side generates messages to be processed (client connection request, client sending data request, client downloading data request) every once in a while, that is, the selector will manage the client side connection and the client side read and write requests in the channel at the same time.
② Main differences between NIO and IO
2. NIO implementation network program
① Create two java projects
The steps are the same as before
② Code part
- service side coding
package com.company; 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; public class Main { //Network communication, IO operation, TCP protocol, optional channel for stream oriented listening socket (generally used for server) private ServerSocketChannel serverSocketChannel; private Selector selector; /* *Open the server */ public void start(Integer port) throws Exception { serverSocketChannel = ServerSocketChannel.open(); selector = Selector.open(); //Binding listening port serverSocketChannel.socket().bind(new InetSocketAddress(port)); //Set to non blocking mode serverSocketChannel.configureBlocking(false); //Register on Selector serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); startListener(); } private void startListener() throws Exception { while (true) { // If the client has a method to request select, the return value will not be zero if (selector.select(1000) == 0) { System.out.println("current not exists task"); continue; } // If there is an event set, the key of the corresponding channel exists Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); // Traverse all keys to find the key with the event type of Accept while (iterator.hasNext()) { SelectionKey key = iterator.next(); if (key.isAcceptable()) handleConnection(); if (key.isReadable()) handleMsg(key); iterator.remove(); } } } /** * Process connection establishment */ private void handleConnection() throws Exception { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } /* * Receive information */ private void handleMsg(SelectionKey key) throws Exception { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer attachment = (ByteBuffer) key.attachment(); channel.read(attachment); System.out.println("current msg: " + new String(attachment.array())); } public static void main(String[] args) throws Exception { Main myServer = new Main(); myServer.start(8888); } }
- Client side coding
package com.company; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class Main { public static void main(String[] args) throws Exception { SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); // Connect server if (!socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888))) { while (!socketChannel.finishConnect()) { System.out.println("connecting..."); } } //send data String str = "hello netty"; ByteBuffer byteBuffer = ByteBuffer.wrap(str.getBytes()); socketChannel.write(byteBuffer); System.in.read(); } }
③ Operation results
3, Netty implements TCP chat program
1. Introduction to Netty
① Netty definition
Netty is a client-side and server-side programming framework based on NIO.
② Netty features
- Using Netty can ensure that you can develop a network application quickly and easily.
- Netty is a well-designed project that absorbs the implementation experience of a variety of protocols, including FTP, SMTP, HTTP, various binary and text protocols.
- Netty not only ensures that the program is easy to develop, but also ensures the high performance, stability and scalability of the application.
2. Netty implementation network program
① Create two new java projects (one Server side and one client side)
Same as above
② Download and add related packages
- Basic steps
- Search input io Netty: netty all, wait a few minutes
- Select Download
- Add package
③ Code part - Server side coding
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import java.net.InetSocketAddress; /** * */ public class Server { private int port; public static void main(String[] args){ new Server(18080).start(); } public Server(int port) { this.port = port; } public void start() { /** * Create two eventloopgroups, that is, two thread pools. The boss thread pool is used to receive client connections, * A thread listens to one port. Generally, it only listens to one port, so only one thread is required * work The pool is used to process network connection data reading and writing or subsequent business processing (another thread can be specified to process business, * work Complete data reading and writing) */ EventLoopGroup boss = new NioEventLoopGroup(1); EventLoopGroup work = new NioEventLoopGroup(); try { /** * Instantiate a server startup class, * group()Specify thread group * channel()Specifies the class used to receive client connections, corresponding to Java nio. ServerSocketChannel * childHandler()Sets the class for encoding, decoding and processing connections */ ServerBootstrap server = new ServerBootstrap() .group(boss, work).channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline() .addLast("decoder", new StringDecoder()) .addLast("encoder", new StringEncoder()) .addLast(new HelloWorldServerHandler()); } }); //Binding port ChannelFuture future = server.bind().sync(); System.out.println("server started and listen " + port); future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); }finally { boss.shutdownGracefully(); work.shutdownGracefully(); } } public static class HelloWorldServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("HelloWorldServerHandler active"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("server channelRead.."); System.out.println(ctx.channel().remoteAddress()+"->Server :"+ msg.toString()); ctx.write("server write"+msg); ctx.flush(); } } }
- Client side coding
import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; /** * */ public class Client { private static final String HOST = "localhost"; private static final int PORT= 18080; public static void main(String[] args){ new Client().start(HOST, PORT); } public void start(String host, int port) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap client = new Bootstrap().group(group).channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline() .addLast("decoder", new StringDecoder()) .addLast("encoder", new StringEncoder()) .addLast(new HelloWorldClientHandler()); } }); ChannelFuture future = client.connect(host, port).sync(); future.channel().writeAndFlush("Hello Netty Server ,I am a netty client"); future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } public static class HelloWorldClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("HelloWorldClientHandler Active"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("HelloWorldClientHandler read Message:"+msg); } } }
④ Operation results
4, Summary
Have a certain understanding of some basic concepts of IO, NIO and Netty, and successfully implement the C/S mode chat program based on TCP
Reference articles
java program implementation of Client/Server based on IO/NIO/Netty
[IDEA] TCP network chat program based on IO, NIO and Netty