Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Two ways to realize Socket VS NIO in simple chat system

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)06/01 Report--

It is said that a simple chat system is not a system at all, but a prototype at best. The focus of this paper is not on the design and implementation of the chat system, but to show the difference between NIO and Socket programming methods by achieving similar effects. It is said that the programming way of Socket and NIO is not very rigorous, because the bottom layer of NIO is also realized through Socket, but can not think of a very good topic, that's it.

Main content

Realizing the effect of simple chat by Socket

Realizing the effect of simple chat by NIO

Performance comparison of the two methods

Preface

The expected effect is a "broadcast" chat between clients, similar to QQ group chat. Hope to have the opportunity in the future, based on this simple version, continue to evolve, practice the online chat system.

Realizing the effect of simple chat by 1.Socket

1.1 Server Server.java

Package com.example.socket.server;import java.io.IOException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;public class Server {private static int port = 9999; / / the maximum length of the acceptable request queue private static int backlog=100; / / bound to the local IP address private static final String bindAddr = "127.0.0.1" / / socket dictionary list private static List nodes= new ArrayList (); public static void main (String [] args) {try {ServerSocket ss = new ServerSocket (port, backlog,InetAddress.getByName (bindAddr)); for (;) {/ / blocking, waiting for client connection Socket sc = ss.accept () Nodes.add (sc); InetAddress addr = sc.getLocalAddress (); System.out.println ("create new session from" + addr.getHostName () + ":" + sc.getPort () + "\ n") / / start two threads for a Socket client, receiving and sending messages new Thread (new ServerMessageReceiver (sc,nodes)) .start (); new ServerMessageSender (sc) .start ();}} catch (IOException e) {e.printStackTrace ();}

1.2 message receiver ServerMessageReceiver.java

Additional responsibility for information broadcasting

Package com.example.socket.server;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;import java.util.ArrayList;import java.util.List;/** receive messages * * / public class ServerMessageReceiver implements Runnable {private Socket socket; / / socket dictionary list private List nodes= new ArrayList () Public ServerMessageReceiver (Socket sc,List nodes) {this.socket=sc; this.nodes=nodes;} / * message broadcast to other nodes * / @ Override public void run () {try {BufferedReader reader = new BufferedReader (new InputStreamReader (socket.getInputStream (), "UTF-8")); / / received message String content While (true) {if (socket.isClosed ()) {System.out.println ("Socket is closed and cannot get message"); reader.close (); socket.close (); break;} content=reader.readLine () If (contentless null & & content.equals ("bye")) {System.out.println ("the other party requests to close the connection and cannot continue the chat"); reader.close (); socket.close (); break } String message = socket.getPort () + ":" + content; / / broadcast message for (Socket n:this.nodes) {if (n! = this.socket) {BufferedWriter writer=new BufferedWriter (new OutputStreamWriter (n.getOutputStream (), "UTF-8")) Writer.write (message); writer.newLine (); writer.flush ();} catch (IOException e) {e.printStackTrace ();}

1.3 message sending server ServerMessageSender.java

Main function: send welcome message

Package com.example.socket.server;import java.io.BufferedWriter;import java.io.IOException;import java.io.OutputStreamWriter;import java.net.Socket;public class ServerMessageSender extends Thread {private Socket socket; public ServerMessageSender (Socket socket) {this.socket = socket } / * send only a welcome message * / @ Override public void run () {try {BufferedWriter writer=new BufferedWriter (new OutputStreamWriter (socket.getOutputStream (), "UTF-8")); / / BufferedReader inputReader=new BufferedReader (new InputStreamReader (System.in)); try {String msg= "server: welcome" + socket.getPort (); writer.write (msg) Writer.newLine (); writer.flush ();} catch (IOException e) {e.printStackTrace ();}} catch (Exception e) {e.printStackTrace ();}

1.4 client Client.java

Package com.example.socket.client;import java.net.InetAddress;import java.net.Socket;public class Client {/ / listener port number private static final int port = 9999; / / IP address bound to the local machine private static final String bindAddr = "127.0.0.1"; public static void main (String [] args) {try {System.out.println ("connecting to Socket server") Socket socket=new Socket (InetAddress.getByName (bindAddr), port); System.out.println ("connected\ nneighbor ="); new ClientMessageSender (socket). Start (); new ClientMessageReceiver (socket). Start ();} catch (Exception e) {e.printStackTrace ();}

1.4 message receiving client ClientMessageReceiver.java

Just output.

Package com.example.socket.client;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.Socket;public class ClientMessageReceiver extends Thread {private Socket socket; public ClientMessageReceiver (Socket socket) {this.socket=socket } @ Override public void run () {try {/ / get the output\ inflow of socket BufferedReader reader = new BufferedReader (new InputStreamReader (socket.getInputStream (), "UTF-8")); / / received message String content While (true) {if (socket.isClosed ()) {System.out.println ("Socket is closed and cannot get message"); reader.close (); socket.close (); break;} content=reader.readLine () If (content.equals ("bye")) {System.out.println ("the other party requests to close the connection and cannot continue the chat"); reader.close (); socket.close (); break;} System.out.println (content+ "\ n") } reader.close (); socket.close ();} catch (Exception e) {e.printStackTrace ();}

1.5 message sending client ClientMessageSender.java

Input the information into Socket through the input stream

Package com.example.socket.client;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;public class ClientMessageSender extends Thread {private Socket socket; public ClientMessageSender (Socket socket) {this.socket = socket } @ Override public void run () {try {BufferedWriter writer=new BufferedWriter (new OutputStreamWriter (socket.getOutputStream (), "UTF-8")); BufferedReader inputReader=new BufferedReader (new InputStreamReader (System.in)); try {String msg; for (;) {msg=inputReader.readLine () If (msg.toLowerCase (). Equals ("exit")) {System.exit (0);} if (socket.isClosed ()) {System.out.println ("Socket is closed and cannot send message"); writer.close () Socket.close (); break;} writer.write (msg); writer.newLine (); writer.flush (); System.out.println () }} catch (IOException e) {e.printStackTrace ();}} catch (Exception e) {e.printStackTrace ();}

1.6 effect

Realizing the effect of simple chat by 2.NIO

2.1 Server NServer.java

Package com.example.nio;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.Channel;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;/** * server side * / public class NServer {private Selector selector; private Charset charset = Charset.forName ("UTF-8") Public void init () throws Exception {selector = Selector.open (); ServerSocketChannel server = ServerSocketChannel.open (); InetSocketAddress isa = new InetSocketAddress ("127.0.0.1", 3000); server.socket () .bind (isa); server.configureBlocking (false); server.register (selector, SelectionKey.OP_ACCEPT) While (selector.select () > 0) {for (SelectionKey key: selector.selectedKeys ()) {selector.selectedKeys () .remove (key); if (key.isAcceptable ()) {SocketChannel sc = server.accept (); System.out.println ("create new session from" + sc.getRemoteAddress () + "\ n") Sc.configureBlocking (false); sc.register (selector, SelectionKey.OP_READ); key.interestOps (SelectionKey.OP_ACCEPT); sc.write (charset.encode ("welcome" + sc.getRemoteAddress () } if (key.isReadable ()) {SocketChannel sc = (SocketChannel) key.channel (); ByteBuffer buff = ByteBuffer.allocate (1024); String content = "" Try {while (sc.read (buff) > 0) {buff.flip (); content + = charset.decode (buff); buff.clear () } key.interestOps (SelectionKey.OP_READ);} catch (IOException e) {key.cancel (); if (key.channel ()! = null) key.channel () .close () } if (content.length () > 0) {for (SelectionKey sk: selector.keys ()) {Channel targetchannel = sk.channel (); if (targetchannel instanceof SocketChannel & & targetchannel channels (c)) {SocketChannel dest = (SocketChannel) targetchannel Dest.write (charset.encode (content));}} public static void main (String [] args) throws Exception {new NServer (). Init ();}}

2.2 client NClient.java

Package com.example.nio;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.nio.charset.Charset;import java.util.Scanner;/** * client * / public class NClient {private Selector selector; private Charset charset = Charset.forName ("UTF-8"); private SocketChannel sc = null Public void init () throws IOException {selector = Selector.open (); InetSocketAddress isa = new InetSocketAddress ("127.0.0.1", 3000); sc = SocketChannel.open (isa); sc.configureBlocking (false); sc.register (selector, SelectionKey.OP_READ); new ClientThread (). Start (); @ SuppressWarnings ("resource") Scanner scan = new Scanner (System.in) While (scan.hasNextLine ()) {sc.write (charset.encode (scan.nextLine () }} private class ClientThread extends Thread {public void run () {try {while (selector.select () > 0) {for (SelectionKey sk: selector.selectedKeys ()) {selector.selectedKeys () .remove (sk) If (sk.isReadable ()) {SocketChannel sc = (SocketChannel) sk.channel (); ByteBuffer buff = ByteBuffer.allocate (1024); String content = "" While (sc.read (buff) > 0) {sc.read (buff); buff.flip (); content + = charset.decode (buff); buff.clear () } System.out.println ("chat info:" + content); sk.interestOps (SelectionKey.OP_READ);} catch (IOException e) {e.printStackTrace () }} public static void main (String [] args) throws IOException {new NClient (). Init ();}}

The code comes from

Https://github.com/xeostream/chat

2.3 effect

3. Contrast

From the point of view of API operation, NIO is complex and oriented to asynchronous programming, focusing on Selector,SelectKey operation.

Performance comparison, mainly simply simulate the Echo scenario: the client connects successfully and the server returns a message.

3.1Socket performance Test Portal

You can close the ServerMessageReceiver thread

Package com.example.socket.client;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class BenchmarkClient {/ / listener port number private static final int port = 9999 / / IP address bound to the machine private static final String bindAddr = "127.0.0.1"; / * * @ param * @ param args * / public static void main (String [] args) {try {long s=System.currentTimeMillis (); for (int I = 0; I

< 1000; i++) { final Socket socket = new Socket( InetAddress.getByName(bindAddr), port); Future future = Executors.newFixedThreadPool(4).submit( new Callable() { @Override public String call() throws Exception { BufferedReader reader = new BufferedReader( new InputStreamReader(socket .getInputStream(), "UTF-8")); String content = reader.readLine(); return Thread.currentThread().getName()+"--->

"+ content;}}); System.out.println (I +": "+ future.get ()); socket.close ();} long e=System.currentTimeMillis (); System.out.println (eMurs) } catch (UnknownHostException e) {e.printStackTrace ();} catch (IOException e) {e.printStackTrace ();} catch (InterruptedException e) {e.printStackTrace ();} catch (ExecutionException e) {e.printStackTrace ();}

3.2 NIO performance Test Portal

Package com.example.nio;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;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.nio.charset.Charset;import java.util.Scanner;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.Executors;import java.util.concurrent.Future / * * client * @ author arthur * / public class BenchMarkNClient {private Selector selector; private Charset charset = Charset.forName ("UTF-8"); private SocketChannel sc = null; public void init () throws IOException {long s = System.currentTimeMillis (); selector = Selector.open (); InetSocketAddress isa = new InetSocketAddress ("127.0.0.1", 3000); for (int I = 0; I

< 10000; i++) { sc = SocketChannel.open(isa); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); Future future = Executors.newFixedThreadPool(4).submit(new ClientTask()); try { System.out.println(i+":"+future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } long e= System.currentTimeMillis(); System.out.println(e-s); } private class ClientTask implements Callable { public String call() { try { while (selector.select() >

0) {for (SelectionKey sk: selector.selectedKeys ()) {selector.selectedKeys () .remove (sk); if (sk.isReadable ()) {SocketChannel sc = (SocketChannel) sk.channel (); ByteBuffer buff = ByteBuffer.allocate (1024) String content = ""; while (sc.read (buff) > 0) {sc.read (buff); buff.flip (); content + = charset.decode (buff) Buff.clear ();} sk.interestOps (SelectionKey.OP_READ); return content } catch (IOException e) {e.printStackTrace ();} return null;}} public static void main (String [] args) throws IOException {new BenchMarkNClient () .init ();}}

3.3 performance comparison

Times

NIO

SOCKET (ms)

one thousand

five hundred and twenty five

6372000

14111215

2000 (sleep time is 100ms)

2059282063135000

6731

2976

The performance of NIO is better when the number of times is less. However, as the number of times increases, the performance degrades very much. (doubtful)

When the communication time becomes longer, it is found that the performance of NIO is relatively improved.

It can be seen that the quality of a technology is inseparable from the business scenario.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report