socket从io到nio

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket从io到nio相关的知识,希望对你有一定的参考价值。

socket的io

server端

package com.chan.service;


import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * ClassName: SocketServer <br/>
 * Description: <br/>
 * date: 2022/7/20 9:52<br/>
 *
 * @author fchen<br />
 */
public class SocketServerService 


    public static void main(String[] args) throws IOException 

        ServerSocket serverSocket = new ServerSocket(8000);
        new Thread(() -> 
            while (true) 

                try 
                    Socket socket = serverSocket.accept();

                    new Thread(() -> 

                        int len;
                        byte[] data = new byte[1024];

                        try 

                            InputStream inputStream = socket.getInputStream();

                            while ((len = inputStream.read(data)) != -1)
                                System.out.println(new String(data, 0, len));
                            

                         catch (IOException e) 
                            e.printStackTrace();
                        


                    ).start();

                 catch (IOException e) 
                    e.printStackTrace();
                
            
        ).start();
    



client端

package com.chan.service;

import java.io.IOException;
import java.net.Socket;
import java.util.Date;

/**
 * ClassName: SocketClientService <br/>
 * Description: <br/>
 * date: 2022/7/20 10:07<br/>
 *
 * @author fchen<br />
 */
public class SocketClientService 


    public static void main(String[] args) 
        new Thread(() -> 

            try 
                Socket socket = new Socket("127.0.0.1", 8000);

                while (true) 

                    socket.getOutputStream().write((new Date() + ":hello wprld").getBytes());
                    Thread.sleep(2000);
                

             catch (IOException e) 
                e.printStackTrace();
             catch (InterruptedException e) 
                e.printStackTrace();
            
        ).start();
    

socket的nio

package com.chan.nio.service;

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.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

/**
 * ClassName: NioserverService <br/>
 * Description: <br/>
 * date: 2022/7/20 10:41<br/>
 *
 * 在io中每个channel都需要一个线程去监听,大多时间这些channel都是没有数据的
 * 那么把这些channel对应到一个线程中去处理,这就是nio的想法
 *
 * @author fchen<br />
 */
public class NIOServerService 

    public static void main(String[] args) throws IOException 

        //serverSelector负责轮询是否有新的连接
        Selector serverSelector = Selector.open();
        //clientSelector负责轮询连接是否有数据可读
        Selector clientSelector = Selector.open();

        //服务端监测到新的连接之后,不再创建一个新的线程,而是直接将新连接绑定到clientSelector上;
        //clientSelector被一个 while 死循环包裹着,如果在某一时刻有多条连接有数据可读,
        //那么通过 clientSelector.select(1)方法可以轮询出来,进而批量处理;

        new Thread(() -> 

            try 

                // 对应IO编程中服务端启动
                ServerSocketChannel listenerChannel = ServerSocketChannel.open();

                listenerChannel.socket().bind(new InetSocketAddress(8000));
                listenerChannel.configureBlocking(false);
                listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT);

                while (true)

                    // 监测是否有新的连接,这里的1指的是阻塞的时间为 1ms
                    if(serverSelector.select(1) > 0)
                        Set<SelectionKey> selectionKeys = serverSelector.selectedKeys();
                        Iterator<SelectionKey> iterator = selectionKeys.iterator();

                        while (iterator.hasNext()) 

                            SelectionKey key = iterator.next();

                            if(key.isAcceptable())

                                try 
                                    SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
                                    clientChannel.configureBlocking(false);
                                    clientChannel.register(clientSelector, SelectionKey.OP_READ);
                                 finally 
                                    iterator.remove();
                                
                            
                        
                    
                

             catch (IOException e) 
                e.printStackTrace();
            
        ).start();



        new Thread(() -> 

            while (true) 

                try 
                    //批量轮询是否有哪些连接有数据可读,这里的1指的是阻塞的时间为 1ms
                    if(clientSelector.select(1) > 0)
                        Set<SelectionKey> selectionKeys = clientSelector.selectedKeys();
                        Iterator<SelectionKey> iterator = selectionKeys.iterator();

                        while (iterator.hasNext()) 

                            SelectionKey key = iterator.next();

                            if(key.isReadable())

                                try 
                                    SocketChannel clientChannel = (SocketChannel) key.channel();
                                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                                    clientChannel.read(byteBuffer);
                                    byteBuffer.flip();
                                    System.out.println(
                                            Charset.defaultCharset().newDecoder().decode(byteBuffer).toString()
                                    );
                                 finally 
                                    iterator.remove();
                                    key.interestOps(SelectionKey.OP_READ);
                                

                            
                        
                    

                 catch (IOException e) 
                    e.printStackTrace();
                
            
        ).start();

    



以上是关于socket从io到nio的主要内容,如果未能解决你的问题,请参考以下文章

什么是NIO异步通信?

Java TCP/IP SocketJava NIO Socket VS 标准IO Socket

java NIO

Java NIO应用实例

java NIO

java NIO