zoukankan      html  css  js  c++  java
  • ServerSocketChannel简述

    一.前言

    前篇文章中了解了SocketChannel:提供了连接到套接字通道,从某种层面而言,NIO中提供了类似于java.net包中对于网络操作的api的功能。既然已经有连接到Socket套接字的通道,可以主动发起连接、传输数据,还缺少接收连接(client端)。不言而喻,还缺少接收连接,接收数据的通道(server端)。这篇文章就主要介绍监听套接字的通道ServerSocketChannel。

    二.ServerSocketChannel

    A selectable channel for stream-oriented listening sockets.

    上述摘自java docs中定义:ServerSocketChannel是面向流的监听socket套接字的可选择性通道。从定义中可以看出以下几点:

    • 具有阻塞和非阻塞两种模式
    • 可以注册到多路复用器上
    • 基于TCP连接
    • 需要绑定到特定端口上

    ServerSocketChannel可以被无参的open()方法创建。但是改方法只是创建了一个ServerSocketChannel对象,并没有进行绑定操作,仍需要调用bind()方法进行绑定,使之监听某个套接字。未进行绑定的ServerSocketChannel调用accept(),将会抛出NotYetBoundException异常。

    ServerSocketChannel支持的可选参数:

    参数名 作用描述
    SO_RCVBUF 套接字接收缓冲区大小
    SO_REUSEADDR 重新使用地址

    ServerSocketChannel支持两种模式:阻塞模式和非阻塞模式。且是线程安全的

    三.ServerSocketChannel使用

    1.创建ServerSocketChannel
    ServerSocketChannel channel = ServerSocketChannel.open();  //创建ServerSocketChannel 
    
    2.绑定到本机网络接口
    channel.bind(new InetSocketAddress(8091));  //绑定至8091端口
    
    3.接收连接
    SocketChannel socketChannel = channel.accept();
    

    ServerSocketChannel的accept方法返回SocketChannel套接字通道,用于读取请求数据和写入响应数据。
    ServerSocketChannel的阻塞和非阻塞体现在这里:

    • 阻塞模式:在调用accept方法后,将阻塞知道有新的socket连接时返回SocketChannel对象,代表新建立的套接字通道。
    • 非阻塞模式:在调用accept方法后,如果无连接建立,则返回null;如果有连接,则返回SocketChannel。

    四.简单的client-server

    创建简单的server:

    public void createServerSocketChannel() throws IOException {
        ServerSocketChannel channel = ServerSocketChannel.open();
        channel.bind(new InetSocketAddress(8091));
        while (true) {
            SocketChannel socketChannel = channel.accept();
            ByteBuffer byteBuffer = ByteBuffer.allocate(16);
            int count = socketChannel.read(byteBuffer);
            while(count != -1) {
                byteBuffer.flip();
                 while (byteBuffer.hasRemaining()) {
                     System.out.print((char) byteBuffer.get());
                 }
                 byteBuffer.clear();
                count = socketChannel.read(byteBuffer);
            }
            System.out.println();
        }
    }
    

    创建简单client:

    public void client() throws IOException {
        SocketChannel socketChannel = SocketChannel.open(
            new InetSocketAddress("10.17.83.11", 8091));
        String msg = "ok";
        socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
    
        SocketChannel socketChannel3 = SocketChannel.open(
            new InetSocketAddress(8091));
        socketChannel3.write(ByteBuffer.wrap(msg.getBytes()));
        System.out.println("s3");
    
        SocketChannel socketChannel4 = SocketChannel.open(
            new InetSocketAddress(8091));
        socketChannel4.write(ByteBuffer.wrap(msg.getBytes()));
        System.out.println("s4");
    
        socketChannel4.close();
        socketChannel3.close();
        socketChannel.close();
    }
    

    ServerSocketChannel基本上不会单独使用绝大多数情况下都是配合多路复用Selector选择器共同使用。这里只关注ServerSocketChannel本身,关于其与多路复用混合使用,后面再介绍Selector时再做详细介绍!

    参考

    本机ip、127.0.0.1和0.0.0.0区别

  • 相关阅读:
    C#数组学习
    关于servlet中要写初始化逻辑应该重载有参还是无参的init
    servlet初识servletConfig
    servlet通过响应头Content-Disposition实现文件下载效果
    response中setCharacterEncoding和setContentType的区别
    通过refresh响应头,定时刷新或隔n秒跳转页面
    通过location响应头实现重定向
    三层交换原理
    什么是CLOS架构?
    Cat8 八类网线是什么?与Cat5、Cat6、Cat7网线的区别?
  • 原文地址:https://www.cnblogs.com/lxyit/p/9224248.html
Copyright © 2011-2022 走看看