ocket 连接建立过程

简介:

阻塞模式下:

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

serverSocket = new ServerSocket(port,3);

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

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

socket = serverSocket.accept();

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

 

2,server端未执行到

  serverSocket = new ServerSocket(port,3);

时,client端执行了

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

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

 

3,server端执行了

 serverSocket = new ServerSocket(port,3);

之后,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值,代表发生的事件的数目。

参考一段代码:

复制代码
1 while(!shutdown){
2                 try{
3                     registerTargets();
4                     if(selector.select() > 0)
5                         processSelectedKeys();
6                 }catch(Exception e){
7                     e.printStackTrace();
8                 }
9             }
复制代码

假设线程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 = 1 << 4;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_WRITE = 1 << 2;

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

SelectionKey集合分以下三种:

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

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

 本文转自hapjin博客园博客,原文链接:http://www.cnblogs.com/hapjin/p/5146631.html,如需转载请自行联系原作者

相关文章
|
1月前
|
人工智能 运维 安全
云栖专刊 | 深度解读阿里云网络全新能力升级,助力企业出海和AI创新
阿里云飞天洛神云网络在2025云栖大会发布全新升级,聚焦企业出海与AI创新,推出确定性网络、智能云网络及AI for Network三大能力,提升全球连接质量,构建高效、安全、智能的云网络底座。
239 8
云栖专刊 | 深度解读阿里云网络全新能力升级,助力企业出海和AI创新
|
3月前
|
SQL Shell 网络安全
vulnhub靶机实战_DC-8
本文介绍DC-8靶机渗透全过程,涵盖环境搭建、信息扫描、SQL注入、密码爆破、反向Shell获取及提权。利用sqlmap与john工具破解用户凭据,通过Web表单执行命令并获取root权限,最终读取flag完成渗透测试。
378 0
|
4月前
|
前端开发 数据可视化 关系型数据库
如何开发设备管理系统中的设备保修维修板块 ?(附架构图+流程图+代码参考)
设备管理系统中的保修维修模块对提升企业效率至关重要。本文详解该模块的设计与实现,涵盖功能规划、业务流程、开发技巧及效果展示,助力企业高效管理设备维修与报废流程。
快手自动抢红包辅助插件,快手抢红包福袋脚本全自动,智能抢包软件按键版
这是一套快手自动抢红包插件源码,通过模拟点击实现自动化操作。例如准备100个快手账号配合此插件挂机抢红包
CPU的工作原理基于其内部结构,通过执行指令来完成各种任务
CPU的工作原理基于其内部结构,通过执行指令来完成各种任务
446 3
|
11月前
|
敏捷开发 人工智能 安全
支付宝故障,如果你来设计会怎么做?
支付宝官方发布公告,解释了因配置错误导致部分用户享受立减优惠的情况。明确表示不会追回已发放的优惠,并提醒用户谨防诈骗短信。针对此次事件,作者从角色缺失、防呆设计、程序预检、沙箱与灰度发布及AI审核五个方面,探讨如何避免类似运营失误,强调了流程优化和责任分担的重要性。
248 1
|
存储 监控 物联网
计算机网络的应用
计算机网络已深入现代生活的多个方面,包括通信与交流(电子邮件、即时通讯、社交媒体)、媒体与娱乐(在线媒体、在线游戏)、商务与经济(电子商务、远程办公)、教育与学习(在线教育平台)、物联网与智能家居、远程服务(远程医疗、智能交通系统)及数据存储与处理(云计算、数据共享与分析)。这些应用极大地方便了人们的生活,促进了社会的发展。
708 2
计算机网络的应用
|
数据采集 前端开发 JavaScript
除了网页标题,还能用爬虫抓取哪些信息?
爬虫技术可以抓取网页上的各种信息,包括文本、图片、视频、链接、结构化数据、用户信息、价格和库存、导航菜单、CSS和JavaScript、元数据、社交媒体信息、地图和位置信息、广告信息、日历和事件信息、评论和评分、API数据等。通过Python和BeautifulSoup等工具,可以轻松实现数据抓取。但在使用爬虫时,需遵守相关法律法规,尊重网站的版权和隐私政策,合理控制请求频率,确保数据的合法性和有效性。
|
Web App开发 监控 网络协议
QUIC 简介及 NodeJs 简单示例
QUIC协议是一个新的通讯协议,基于 UDP 的传输协议并希望最终取代所有基于TCP的HTTP请求。熟悉 UDP 的人都应该清楚为什么要使用 QUIC。UDP 是的特点是不可靠、数据包经常丢失、重新排序、重复等等。UDP 不包括任何更高级别协议(如 HTTP)严格要求的 TCP 的可靠性和顺序保证,这就是 QUIC 的用武之地。
883 0
QUIC 简介及 NodeJs 简单示例
|
缓存 安全 网络协议
HTTP协议中Via的用法
【5月更文挑战第29天】Web请求通过代理服务器的情况,强调了随着代理的普及,追踪报文流以解决网络问题的重要性。