阻塞模式下:

1,客户端向服务器端发起请求建立连接时,服务器端只需要运行到

serverSocket = new ServerSocket(port,);

客户端注册的  SelectionKey.OP_CONNECT 事件就能够发生。

也就是说,不需要等到服务器端执行到

socket = serverSocket.accept();

客户端注册的SelectionKey.OP_CONNECT 通过 select()查询时就返回一个 大于 0 的值了。

2,server端未执行到

serverSocket = new ServerSocket(port,);

时,client端执行了

socket.connect(new InetSocketAddress(host, port));

时,抛出异常:Exception in thread "main" java.net.ConnectException: Connection refused: connect

3,server端执行了

 serverSocket = new ServerSocket(port,);

之后,client端执行

socket.connect(new InetSocketAddress(host, port));

System.out.println("connection accepted " + socket.getInetAddress() + ":" + socket.getPort());

时,能成功执行,且输出:connection accepted localhost/127.0.0.1:8000

然后client 能够给server发送数据。但只有到server执行了 accpet()后,才能受理client的数据。

4,关于SocketChannel类的connect()方法作用

当SocketChannel工作于非阻塞模式下时,调用connect()时会立即返回:如果连接建立成功则返回的是true(比如连接localhost时,能立即建立起连接),否则返回false。在非阻塞模式下,返回false后,必须要在随后的某个地方调用finishConnect()方法完成连接。

当SocketChannel处于阻塞模式下时,调用connect()时会进入阻塞,直至连接建立成功或者发生IO错误时,才从阻塞状态中退出。

5,Selector.select()方法从阻塞状态返回的详细过程 和 ServerSocket.accpet()方法从阻塞状态返回的过程

select()方法:如果事件注册或者已经注册的事件没有发生。调用select()方法的线程将会被阻塞。该线程可以通过如下方法退出阻塞状态:

①其他线程执行了同一个Selector的wakeup()方法将之唤醒,在这种情况下,select()返回值为0。表明它是被wakeup()唤醒的,而不是因为有注册的事件发生了而唤醒的。

②注册到Selector上的事件发生了。此时,线程也会从阻塞状态中退出,并且select()方法返回一个非0值,代表发生的事件的数目。

参考一段代码:

 while(!shutdown){
try{
registerTargets();
if(selector.select() > )
processSelectedKeys();
}catch(Exception e){
e.printStackTrace();
}
}

假设线程A执行到第4行的if语句中的select()方法时,进入了阻塞状态:

如果另外一个线程执行 selector.wakeup() 。该线程(线程A)将会被唤醒,然后select()方法返回一个0值(表示没有注册的事件发生),执行if判断,if语句就会不成立,继续下一轮while循环。-----先从select()方法中返回,再执行if判断----“验证了程序总是从段点处往下执行的!!!”

accept()方法从阻塞状态返回的具体细节---假设通道工作在阻塞模式。

当serverSocketChannel.acppet()执行时,若此时没有连接请求到来(准确地说应该是:操作系统管理的连接请求队列为空),线程就会进入阻塞状态。直到下面情况时,从阻塞状态返回:

①被其他线程中断了--不详细讨论

②连接请求到来了(操作系统管理的连接请求队列中有数据了),线程从accept()退出阻塞状态的同时返回一个SocketChannel对象。这个对象就表示:从客户端到服务器端建立起的一条TCP连接。

6,当Selector中注册的事件发生时,底层发生了什么操作?

以OP_ACCEPT事件为例讨论:JDK中关于该事件的注释如下:

Suppose that a selection key's interest set contains OP_ACCEPT at the start of a selection operation. If the selector detects that the corresponding server-socket channel is ready to accept another connection, or has an error pending, then it will add OP_ACCEPT to the key's ready set and add the key to its selected-key set.

首先,selection key的感兴趣的集合中要包含OP_ACCEPT,也即,要把OP_ACCEPT事件注册到Selector中,代码如下:

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

其次,注册了之后,由selector来 detect---检测 相应的 server-socket 通道是否已经准备好接收其他的连接请求,如果准备好了:

就会把OP_ACCEPT添加到这个SelectionKey对象的 就绪事件集合(ready set)中,同时,再把这个SelectionKey对象添加到已选择的Key集合(selected-key set)中。

注意:上面的过程涉及到了两个集合:一个是事件的集合,另一个是SelectionKey对象的集合。明显这两个集合是不同的。事件一共只有如下四种:

public static final int OP_ACCEPT =  << ;
public static final int OP_CONNECT = << ;
public static final int OP_CONNECT = << ;
public static final int OP_WRITE = << ;

事件的集合是附属在某个SelectionKey对象上的。也即,一个SelectionKey对象就拥有一个事件集合。

SelectionKey集合分以下三种:

已注册的键的集合(Registered key set)
已选择的键的集合(Selected key set)
已取消的键的集合(Cancelled key set)

如上面所说,如果selector检测到了通道准备好了接收其他的连接请求,就会把相应的SelectionKey对象添加到已选择的键集合中。

Socket 连接建立过程的更多相关文章

  1. 详解BLE连接建立过程

    同一款手机,为什么跟某些设备可以连接成功,而跟另外一些设备又连接不成功?同一个设备,为什么跟某些手机可以建立连接,而跟另外一些手机又无法建立连接?同一个手机,同一个设备,为什么他们两者有时候连起来很快 ...

  2. 第三次实验报告:使用Packet Tracer分析TCP连接建立过程

    目录 1 实验目的 2 实验内容 3. 实验报告 3.1 建立网络拓扑结构 3.2 配置参数 3.3 抓包,分析TCP连接建立过程 4. 拓展 (不作要求,但属于加分项) 1 实验目的 使用路由器连接 ...

  3. HTTPS连接建立过程(单向&双向)

    HTTPS连接建立过程(单向&双向) 什么是https SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Securit ...

  4. 用Wireshark分析Socket连接建立的过程

    0. 安装Wireshark,但是默认情况下,Wireshark无法捕获127.0.0.1的报文 解决方案:安装npcap,替换默认的winpacp,重新启动Wireshark,就可以看到一个名字中含 ...

  5. memcached客户端连接建立过程笔记

    memcached在启动过程初始化server_sockets时,根据启动参数决定系统是进行tcp监听还是udp监听,这里暂时只关注tcp的情况. server_socket在初始化时会向系统申请监听 ...

  6. 记Windows下初次使用dev C++进行socket编程过程

    记初次接触socket编程,在devC++使用Winsock进行socket编程的一个过程,通过在devC++创建2个项目分别是server.client程序项目,感受通过socket使client与 ...

  7. 抓包分析SSL/TLS连接建立过程【总结】

    1.前言 最近在倒腾SSL方面的项目,之前只是虽然对SSL了解过,但是不够深入,正好有机会,认真学习一下.开始了解SSL的是从https开始的,自从百度支持https以后,如今全站https的趋势越来 ...

  8. 基于TCP的socket通信过程及例子

    Socket也叫套接字,用来实现网络通讯,通过调用系统提供的API,可以和远程的机子传输数据.Socket有很多种协议,而这篇文章主要讨论TCP部分的内容,也就是说后面说的内容主要是指TCP Sock ...

  9. 面向连接的socket数据处理过程以及非阻塞connect问题

    对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后 ...

随机推荐

  1. [转帖]盖国强:Oracle 路线图

    http://www.eygle.com/archives/2018/12/oracle_database_release_19c_confirm.html 盖总的blog 里面讲了下相关的内容. 很 ...

  2. JavaScript从入门到精通

    第一(基本语法) if(condition1){ expression1; }else if(condition2){ expression2; }else{ expression3; } switc ...

  3. linux-shell系列8 netstat用法

    1 查看TCP连接状态 netstat -n|awk '{print $6}'|sort|uniq -c|sort -rn netstat -n|awk '/^tcp/ {++S[$NF]};END{ ...

  4. BZOJ3625 [Codeforces Round #250]小朋友和二叉树(生成函数+多项式开根)

    设f(n)为权值为n的神犇二叉树个数.考虑如何递推求这个东西. 套路地枚举根节点的左右子树.则f(n)=Σf(i)f(n-i-cj),cj即根的权值.卷积的形式,cj也可以通过卷上一个多项式枚举.可以 ...

  5. Redis无法保存ef复杂对象

    最近项目需要使用redis. 然后我就满怀激情开始处理数据层了.在原来查询数据的基础上,有封装了一个redis缓存层. 结果在redis保存ef对象的时候,发现了一个非常尴尬的问题. model: p ...

  6. 覆盖的面积 HDU - 1255(扫描线求面积交)

    题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时  的情况, 所以就要用到一个临时 ...

  7. hdu 2158 最短区间版大家来找碴(尺取法)

    Problem Description 给定一个序列,有N个整数,数值范围为[0,N).有M个询问,每次询问给定Q个整数,可能出现重复值.要求找出一个最短区间,该区间要包含这Q个整数数值.你能找的出来 ...

  8. 牛客练习赛40 C 小A与欧拉路(树的直径)

    链接:https://ac.nowcoder.com/acm/contest/369/C 题目描述 小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点 ...

  9. c语言可变参

    一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,…),int ...

  10. Linux下配置ssh免密远程登录

    步骤 使用ssh-keygen生成密钥对 提示要求输入保存的位置,密码等信息.全部使用默认信息即可 使用ssh-copy-id user@host将公钥拷贝到需要免密登录的服务器的账户中. 例如,需要 ...