聊聊httpclient的connect
序
本文主要研究一下httpclient的connect
HttpClientConnectionOperator
org/apache/http/conn/HttpClientConnectionOperator.java
public interface HttpClientConnectionOperator {void connect(ManagedHttpClientConnection conn,HttpHost host,InetSocketAddress localAddress,int connectTimeout,SocketConfig socketConfig,HttpContext context) throws IOException;void upgrade(ManagedHttpClientConnection conn,HttpHost host,HttpContext context) throws IOException;}
HttpClientConnectionOperator定义了connect及upgrade方法,它有一个默认的实现类为DefaultHttpClientConnectionOperator
DefaultHttpClientConnectionOperator
org/apache/http/impl/conn/DefaultHttpClientConnectionOperator.java
public class DefaultHttpClientConnectionOperator implements HttpClientConnectionOperator {static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry";private final Log log = LogFactory.getLog(getClass());private final Lookup<ConnectionSocketFactory> socketFactoryRegistry;private final SchemePortResolver schemePortResolver;private final DnsResolver dnsResolver;public DefaultHttpClientConnectionOperator(final Lookup<ConnectionSocketFactory> socketFactoryRegistry,final SchemePortResolver schemePortResolver,final DnsResolver dnsResolver) {super();Args.notNull(socketFactoryRegistry, "Socket factory registry");this.socketFactoryRegistry = socketFactoryRegistry;this.schemePortResolver = schemePortResolver != null ? schemePortResolver :DefaultSchemePortResolver.INSTANCE;this.dnsResolver = dnsResolver != null ? dnsResolver :SystemDefaultDnsResolver.INSTANCE;}//......public void connect(final ManagedHttpClientConnection conn,final HttpHost host,final InetSocketAddress localAddress,final int connectTimeout,final SocketConfig socketConfig,final HttpContext context) throws IOException {final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(context);final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());if (sf == null) {throw new UnsupportedSchemeException(host.getSchemeName() +" protocol is not supported");}final InetAddress[] addresses = host.getAddress() != null ?new InetAddress[] { host.getAddress() } : this.dnsResolver.resolve(host.getHostName());final int port = this.schemePortResolver.resolve(host);for (int i = 0; i < addresses.length; i++) {final InetAddress address = addresses[i];final boolean last = i == addresses.length - 1;Socket sock = sf.createSocket(context);sock.setSoTimeout(socketConfig.getSoTimeout());sock.setReuseAddress(socketConfig.isSoReuseAddress());sock.setTcpNoDelay(socketConfig.isTcpNoDelay());sock.setKeepAlive(socketConfig.isSoKeepAlive());if (socketConfig.getRcvBufSize() > 0) {sock.setReceiveBufferSize(socketConfig.getRcvBufSize());}if (socketConfig.getSndBufSize() > 0) {sock.setSendBufferSize(socketConfig.getSndBufSize());}final int linger = socketConfig.getSoLinger();if (linger >= 0) {sock.setSoLinger(true, linger);}conn.bind(sock);final InetSocketAddress remoteAddress = new InetSocketAddress(address, port);if (this.log.isDebugEnabled()) {this.log.debug("Connecting to " + remoteAddress);}try {sock = sf.connectSocket(connectTimeout, sock, host, remoteAddress, localAddress, context);conn.bind(sock);if (this.log.isDebugEnabled()) {this.log.debug("Connection established " + conn);}return;} catch (final SocketTimeoutException ex) {if (last) {throw new ConnectTimeoutException(ex, host, addresses);}} catch (final ConnectException ex) {if (last) {final String msg = ex.getMessage();throw "Connection timed out".equals(msg)? new ConnectTimeoutException(ex, host, addresses): new HttpHostConnectException(ex, host, addresses);}} catch (final NoRouteToHostException ex) {if (last) {throw ex;}}if (this.log.isDebugEnabled()) {this.log.debug("Connect to " + remoteAddress + " timed out. " +"Connection will be retried using another IP address");}}}
}
DefaultHttpClientConnectionOperator的connect先通过getSocketFactoryRegistry获取
Lookup<ConnectionSocketFactory>,再通过它获取ConnectionSocketFactory,之后通过dnsResolver解析地址,再通过schemePortResolver解析port,然后通过ConnectionSocketFactory创建socket,并根据socketConfig设置socket的参数,最后执行connectSocket,并绑定到conn
connectSocket
org/apache/http/conn/socket/PlainConnectionSocketFactory.java
public class PlainConnectionSocketFactory implements ConnectionSocketFactory {public static final PlainConnectionSocketFactory INSTANCE = new PlainConnectionSocketFactory();public static PlainConnectionSocketFactory getSocketFactory() {return INSTANCE;}public PlainConnectionSocketFactory() {super();}@Overridepublic Socket createSocket(final HttpContext context) throws IOException {return new Socket();}@Overridepublic Socket connectSocket(final int connectTimeout,final Socket socket,final HttpHost host,final InetSocketAddress remoteAddress,final InetSocketAddress localAddress,final HttpContext context) throws IOException {final Socket sock = socket != null ? socket : createSocket(context);if (localAddress != null) {sock.bind(localAddress);}try {sock.connect(remoteAddress, connectTimeout);} catch (final IOException ex) {try {sock.close();} catch (final IOException ignore) {}throw ex;}return sock;}}
PlainConnectionSocketFactory的createSocket直接new一个socket,其connectSocket方法则执行sock.connect
socketConfig
resolveSocketConfig
org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java
private SocketConfig resolveSocketConfig(final HttpHost host) {SocketConfig socketConfig = this.configData.getSocketConfig(host);if (socketConfig == null) {socketConfig = this.configData.getDefaultSocketConfig();}if (socketConfig == null) {socketConfig = SocketConfig.DEFAULT;}return socketConfig;}
PoolingHttpClientConnectionManager的resolveSocketConfig先是从configData根据指定host获取socketConfig,若为null则再从configData获取默认的socketConfig,若为null则返回默认的socketConfig
setSocketConfig
org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java
public void setDefaultSocketConfig(final SocketConfig defaultSocketConfig) {this.configData.setDefaultSocketConfig(defaultSocketConfig);}public void setSocketConfig(final HttpHost host, final SocketConfig socketConfig) {this.configData.setSocketConfig(host, socketConfig);}
PoolingHttpClientConnectionManager提供了setDefaultSocketConfig、setSocketConfig方法
SocketConfig.DEFAULT
org/apache/http/config/SocketConfig.java
public class SocketConfig implements Cloneable {public static final SocketConfig DEFAULT = new Builder().build();//......public static class Builder {private int soTimeout;private boolean soReuseAddress;private int soLinger;private boolean soKeepAlive;private boolean tcpNoDelay;private int sndBufSize;private int rcvBufSize;private int backlogSize;Builder() {this.soLinger = -1;this.tcpNoDelay = true;}//......}
}
默认的socketConfig,除了tcpNoDelay为true,其他的都为false,然后soLinger为-1
小结
HttpClientConnectionOperator定义了connect及upgrade方法,它有一个默认的实现类为DefaultHttpClientConnectionOperator;DefaultHttpClientConnectionOperator的connect先通过getSocketFactoryRegistry获取Lookup<ConnectionSocketFactory>,再通过它获取ConnectionSocketFactory,之后通过dnsResolver解析地址,再通过schemePortResolver解析port,然后通过ConnectionSocketFactory创建socket,并根据socketConfig设置socket的参数,最后执行connectSocket,并绑定到conn;默认的socketConfig,除了tcpNoDelay为true,其他的都为false,然后soLinger为-1。
相关文章:
聊聊httpclient的connect
序 本文主要研究一下httpclient的connect HttpClientConnectionOperator org/apache/http/conn/HttpClientConnectionOperator.java public interface HttpClientConnectionOperator {void connect(ManagedHttpClientConnection conn,HttpHost host,InetSocketAddress loca…...
处理视频的新工具:UniFab 2.0.0.4 Crack
UniFab这是一个用于处理视频的新工具,可以帮助您像专业人士一样获得结果,事实上,它可以确保在项目的任何设备上完美播放,所以,来认识一下 UniFab - 一款功能强大且方便的视频编辑器和转换器,但另一方面&…...
设计模式—开闭原则
1.背景 伯特兰迈耶一般被认为是最早提出开闭原则这一术语的人,在他1988年发行的《面向对象软件构造》中给出。这一想法认为一旦完成,一个类的实现只应该因错误而修改,新的或者改变的特性应该通过新建不同的类实现。新建的类可以通过继承的方…...
【开源】基于Vue和SpringBoot的学校热点新闻推送系统
项目编号: S 047 ,文末获取源码。 \color{red}{项目编号:S047,文末获取源码。} 项目编号:S047,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新…...
Java,File类与IO流,处理流:缓冲流、转换流、数据流、对象流
目录 处理流之一:缓冲流 四种缓冲流: 缓冲流的作用: 使用的方法: 处理文本文件的字符流: 处理非文本文件的字节流: 操作步骤: 处理流之二:转换流 转换流的使用: …...
【电路笔记】-分压器
分压器 文章目录 分压器1、概述2、负载分压器3、分压器网络4、无功分压器4.1 电容分压器4.2 感应分压器 5、总结 有时,需要精确的电压值作为参考,或者仅在需要较少功率的电路的特定阶段之前需要。 分压器是解决此问题的一个简单方法,因为它们…...
音视频5、libavformat-3
8、设置I/O中断机制 在 demux 时,我们首先需要调用 avformat_open_input() 打开一个输入,然后循环调用 av_read_frame() 函数来读取输入。 我们要注意的是: avformat_open_input() 和 av_read_frame() 都是阻塞函数,如果不能读取到足够的数据,那么它们将会一直阻塞…...
前端 HTML 和 JavaScript 的基础知识有哪些?
前端开发是Web开发的一个重要领域,涉及到HTML(Hypertext Markup Language)和JavaScript两个主要的技术。HTML用于定义网页的结构和内容,而JavaScript用于实现网页的交互和动态效果。以下是前端HTML和JavaScript的基础知识…...
Android平台GB28181设备接入模块开发填坑指南
技术背景 为什么要开发Android平台GB28181设备接入模块?这个问题不再赘述,在做Android平台GB28181客户端的时候,媒体数据这块,我们已经有了很好的积累,因为在此之前,我们就开发了非常成熟的RTMP推送、轻量…...
我叫:希尔排序【JAVA】
1.我兄弟存在的问题 2.毛遂自荐 希尔排序提希尔(Donald Shell)于1959年提出的一种排序算法。 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的&…...
Spring Cloud Gateway 网关跨域问题解决
0、版本说明 Spring Cloud Version:Spring Cloud 2021.0.4 Spring Cloud Gateway Version:3.1.4 Spring Boot Version:2.6.11 1、网关跨域问题说明 关于跨域的相关原理和理论,网上有大量文章对此进行说明,因此博主在这…...
C++局域网从服务器获取已连接用户的列表(linux to linux)
目录 服务器端 代码 客户端 代码解析 服务器端 原理 遇到的阻碍以及解决办法 客户端 原理 遇到的阻碍以及解决办法 运行结果截图 总结 服务器端 代码 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet…...
c++11新特性篇-可调用对象包装器, 绑定器
可调用对象包装器, 绑定器 可调用对象 可调用对象是指在 C 中能够像函数一样被调用的实体。它包括了多种类型的对象,使得它们能够像函数一样被调用,可以是函数、函数指针、函数对象、Lambda 表达式等。在C中,具有以下特征之一的实体都被认为…...
论文阅读:“Appearance Capture and Modeling of Human Teeth”
文章目录 AbstractIntroductionMethod OverviewTeeth Appearance ModelEnamelDentinGingiva and oral cavity Data AcquisitionImage captureGeometry capture ResultsReferences Abstract 如果要为电影,游戏或其他类型的项目创建在虚拟环境中显示的人类角色&#…...
初学vue3与ts:路由跳转带参数
index-router <!-- 路由跳转 --> <template><div><div class"title-sub flex"><div>1、用router-link跳转带参数id1:</div><router-link to"./link?id1"><button>点我跳转</button>&…...
JAVAEE---多线程
线程安全 这段代码执行结果就就是一个不确定的数,就存在线程安全问题。 为了解决这样的问题我们可以对count进行打包,我们知道count本质上应该是由三个指令完成,我们可以对其打包。 这样的代码结果就是正确的。我们对对象就进行了加锁&#…...
提示工程-Prompt Engineering
提示工程 提示工程 1、概述 Prompt Engineering: 提示工程 通过自然语言(英语、汉语等)来给AI下达指示,从而让AI完成你指定给他的工作的过程都可以称之为提示工程。(面向自然语言编程) 提示词要素 指令&…...
JetLinks设备接入的认识与理解【woodwhales.cn】
为了更好的阅读体验,建议移步至笔者的博客阅读:JetLinks设备接入的认识与理解 1、认识 JetLinks 1.1、官网文档 官网:https://www.jetlinks.cn/ JetLinks 有两个产品:JetLinks-lot和JetLinks-view 官方文档: JetLi…...
机器人开发的选择
喷涂机器人 码垛机器人 纸箱码垛机器人 焊接机器人 跳舞机器人 管道清理机器人 工地巡检机器人 点餐机器人 化工巡检机器人 装箱机器人 安防巡检机器人 迎宾机器人好像有点像软银那个 污水管道检测机器人 大酒店用扫地机器人 家用扫地机器人 工厂用(…...
LeetCode Hot100 102.二叉树的层序遍历
题目: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 方法:迭代 class Solution {public List<List<Integer>> levelOrder(TreeNode root) {if …...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
