zoukankan      html  css  js  c++  java
  • NIO系列2:TCP监听绑定

    注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP监听绑定的过程及细节设计。


    我们一开始设计了一个TCP接入服务类,这个类提供了一个API方法提供对本地一系列地址(端口)的监听绑定,类初始化后完成Selector的open操作如下:

    selector = Selector.open();

    提供的绑定API,其方法签名如下:

     /**
    	 * Binds to the specified local addresses and start to accept incoming connections. If any address binding failed then
    	 * rollback the already binding addresses. Bind is fail fast, if encounter the first bind exception then throw it immediately.
    	 * 
    	 * @param firstLocalAddress
    	 * @param otherLocalAddresses
    	 * @throws throw if bind failed.
    	 */
    	synchronized public void bind(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses) throws IOException;
    

    为何需要同步?因为我们不希望多个线程同时调用该方法,导致地址绑定异常。

    参数中可以传递多个本地地址(端口)同时进行监听绑定。

    在NIO的绑定过程中需进行事件注册(对OP_ACCEPT感兴趣),如下:

      ServerSocketChannel ssc = ServerSocketChannel.open();
    		ssc.configureBlocking(false);
    		ServerSocket ss = ssc.socket();
    		ss.setReuseAddress(config.isReuseAddress());
    		ss.bind(address, config.getBacklog());
    		ssc.register(selector, SelectionKey.OP_ACCEPT);


    由于注册过程中除了涉及锁竞争还可能产生死锁,所以一般的做法都是将绑定地址放在队列中进行异步注册由reactor线程进行处理,例如:

      bindAddresses.addAll(localAddresses);
    		if (!bindAddresses.isEmpty()) {
    			synchronized (lock) {
    				// wake up for unblocking the select() to process binding addresses
    				selector.wakeup();
    
    				// wait for bind result
    				wait0();
    			}
    		}

    从同步注册变为异步注册后就存在一个问题,实际注册绑定时可能存在端口已绑定的异常,在异步情况下就需要线程间通信来通知异常消息,并向调用方反馈。

    如上面代码片段中的wait0()方法就是等待绑定结果,若出现绑定异常则抛出

      private void wait0() throws IOException {
    		while (!this.endFlag) {
    			try {
    				lock.wait();
    			} catch (InterruptedException e) {
    				throw new IOException(e);
    			}
    		}
    
    		// reset end flag
    		this.endFlag = false;
    
    		if (this.exception != null) {
    			IOException e = exception;
    			this.exception = null;
    			throw e;
    		}
    	}

    以上代码也说明了,NIO异步模型转化为同步API导致的模型阻抗付出了额外的代价和开销 --- 线程间通信。

    至此,完成了TCP服务监听过程,下文将进一步讲述服务接入和数据传输相关设计细节。



  • 相关阅读:
    Appium+python自动化13-native和webview切换【转载】
    Appium+python自动化12-appium元素定位【转载】
    Appium+python自动化11-adb必知必会的几个指令【转载】
    Appium+python自动化10-AVD 模拟器【转载】
    Appium+python自动化9-SDK Manager【转载】
    Appium+python自动化8-Appium Python API【转载】
    Appium+python自动化7-输入中文【转载】
    Appium+python自动化6-Remote远程控制【转载】
    Appium+python自动化5-Appium Inspector【转载】
    Centos-内核核心组成
  • 原文地址:https://www.cnblogs.com/hehe520/p/6147658.html
Copyright © 2011-2022 走看看