HTTP服务器实现长连接的思路(Java语言)

一、背景

目前的HTTP服务器很多,只要是编程语言支持线程和网络通信,就能开发一个HTTP协议服务器。

市场上常用的是Tomcat、Ngnix、Httpd等技术。


二、本文目的

介绍使用Java语言来开发HTTP服务器的处理逻辑。

这是个人可以参考的HTTP服务器通用逻辑。


三、工作线程的执行逻辑如下

(一)Java.net.Socket的阻塞式处理

1、从accept()方法处获取Socket对象。2、获取输入和输出流。3、进入循环处理:
while(true){      3.1 判断是否关闭和失去连接,如果任意满足,退出循环。      // 3.2 调用setSoTimeout()方法设置读取超时。      socket.setSoTimeout(3000);// 3.3 调用readRequest()方法读取请求,获得请求对象request。      // 3.4 调用doResponse(out, request)处理方法,把请求对象传入处理请求。      // 3.5 判断是否为长连接,否则退出循环}// 4、关闭套接字
socket.close()

(二)java.nio.channel.SocketChannel的非阻塞式处理


1、当Selector获取一个通道满足可连接要求。2、处理可连接事件,注册可读取事件。3、当满足可读取事件,开始处理读取事件:
while(True){// 3.1循环读取请求while(True){// 3.1.1读取一次数据到缓冲里int size = chnnel.read(buffer);// 3.1.2如果size为0,退出循环。// 说明当前没有数据可读if(size== 0){break;}//  3.1.3翻转,用来读取buffer.flip();// 3.1.4把缓存数据写入请求对象中,用来构造请求request.addData(buffer);// 3.1.5清除缓冲buffer.clear();}// 3.2结束请求的数据,开始解析// 是否需要判断请求是否读取完整?有没有到读取空行request.end()// 3.3开始处理响应,传入请求对象doResponse(request);// 3.4判断当前连接还存在,失去连接就退出循环if(失去连接 || 已关闭){break;}// 3.5判断是否为长连接,不是则退出循环// 3.6设置读取超时时间,防止长时间保持}// 4、关闭该通道// 5、从Selector中移除通道注册

三、注意
1、上述的一些Request和Response对象是自定义的,内部有一些读写方法和其他方法,按照HTTP协议的格式来处理。


2、readRequest和doResponse方法是用户自定义实现的,作用分别是读取请求,返回请求对象;作出响应。


3、其他的都是系统库提供的方法。
例如Socket的方法,InputStream和OutputStream提供的方法。


4、非阻塞读取请求时,不好判断是否把请求全部读取完成了,因为不会阻塞等待,没有数据读取会返回整型数字0。


5、一些变量都是假设定义的。
例如ByteBuffer类型的buffer变量,Socket的socket对象,SocketChannel的channel变量等等。


6、如果想改成一种Servlet容器,只需要用反射生成Servlet对象,生成官方的请求和响应类,传入后执行服务方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Selenium进行元素定位的全面指南

使用Selenium进行元素定位的全面指南 引言 Selenium 是一个广泛使用的开源工具,用于自动化Web浏览器的操作。无论你是进行自动化测试,还是需要抓取网页数据,Selenium 都是一个非常有用的工具。而在Selenium中,定位网页元素是自动…

LabVIEW机械设备故障诊断中,振动分析的有效性与局限性如何

LabVIEW作为一种强大的图形化编程工具,在机械设备故障诊断中的振动分析中发挥了重要作用。振动分析通过监测机械设备的振动信号,能够有效地诊断设备故障。然而,尽管其有效性显著,但也存在一些局限性。本文将探讨LabVIEW在振动分析…

C# —— for循环语句

基本语法 for (初始表达式; 条件表达式; 增量表达式) { // 循环体 } for循环中 有三个空 第一个空(初始表达式): 一般用来声明一个临时的局部变量 用来计数 第二个空(条件表达式): 表明进入循环的条件 一个bool类型的值(bool类型 条…

深度神经网络——什么是NLP(自然语言处理)?

自然语言处理(NLP) 是对使计算机能够处理、分析、解释和推理人类语言的技术和工具的研究和应用。 NLP 是一个跨学科领域,它结合了语言学和计算机科学等领域已建立的技术。 这些技术与人工智能结合使用来创建聊天机器人和数字助理,…

海成蜘蛛池广州官网下载

baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? baidu搜索:如何联系八爪鱼SEO? 当我们给自己的泛目录设置仅蜘蛛抓取生成缓存的时候,我们需要模拟蜘蛛抓取测试我们的设置是否成功。绝大部分时候我们都使用网页蜘蛛模拟抓取测…

Comparable和Comparator区别

相同点:都是用于比较排序。 不同点: 1、接口所在的包不同:comparable:java.lang.Comparable;Comparator:java.util.Comparator 2、比较逻辑不同:Comparable:内部比较器&#xff1…

2024.618到底买什么数码值得?带你一起来看看!

在618期间,这些新品可能会有特别的优惠活动,包括但不限于折扣、满减、赠品等。因此,如果你正在寻找一款适合自己的数码产品,不妨关注各大电商平台的618促销活动,把握机会,以优惠的价格购买到心仪的产品。 …

文件操作(1)(C语言版)

前言: 为什么要学习文件操作: 1、如果大家写过一些代码,当运行结束的时候,这些运行结果将不复存在,除非,再次运行时这些结果才能展现在屏幕上面,就比如之前写过的通讯录。 现实中的通讯录可以保…

【数据结构初阶】--- 堆

文章目录 一、什么是堆?树二叉树完全二叉树堆的分类堆的实现方法 二、堆的操作堆的定义初始化插入数据(包含向上调整详细讲解)向上调整删除堆顶元素(包含向下调整详细讲解)向下调整返回堆顶元素判断堆是否为空销毁 三、…

一个开源的快速准确地将 PDF 转换为 markdown工具

大家好,今天给大家分享的是一个开源的快速准确地将 PDF 转换为 markdown工具。 Marker是一款功能强大的PDF转换工具,它能够将PDF文件快速、准确地转换为Markdown格式。这款工具特别适合处理书籍和科学论文,支持所有语言的转换,并…

2024年最佳插电式混合动力电动汽车

对电动汽车充满好奇和环保意识的司机们还没有准备好跨入纯电动汽车,他们可以找到一个折衷方案,即插电式混合动力车。 在过去的16年里,我一直在把握汽车行业的脉搏。试驾数百辆汽车、电动汽车、插电式混合动力车,跟踪汽车行业的新闻…

python2.7pip报错:UnicodeDecodeError: ‘ascii‘ codec can‘t decode

找到文件&#xff1a;<yourpath>\Python27\Lib\ntpath.py&#xff0c;修改join函数&#xff1a; # Join two (or more) paths. def join(path, *paths):"""Join two or more pathname components, inserting "\\" as needed."""…

DAY04 HTMLCSS

文章目录 一 表单(1) 数字控件(2) 颜色控件(3) 日期控件(4) 月份控件(5) 星期控件(6) 搜索控件(7) 范围控件 二 浮动框架三 结构化标签四 CSS1 CSS概述2 CSS的编写位置1. inline style 行内样式2. inner style 内部样式3. outer style 外部样式4. 小结 3 CSS选择器1. 通用选择器…

NumPy 差分、最小公倍数、最大公约数、三角函数详解

NumPy 差分 离散差分意味着相邻元素之间的减法。 例如&#xff0c;对于 [1, 2, 3, 4]&#xff0c;离散差分将是 [2-1, 3-2, 4-3] [1, 1, 1] 要找到离散差分&#xff0c;使用 diff() 函数。 示例&#xff1a; import numpy as nparr np.array([10, 15, 25, 5])newarr np…

一个示例学习C语言到汇编层面

给出以下代码 #include<stdio.h> int main() {int x 0, y 0, z 0;while (1) {x 0;y 1;do {printf("%d\n", x);z x y;x y;y z;} while (x < 255);}return 0; }我们把这个程序编写成32位程序&#xff0c;然后我们放入IDA中进行分析 .text:0080187…

Mysql开启查询日志(General Log)

1、增加配置&#xff1a; /etc/my.cnf [mysqld] general_log1 general_log_file/var/log/mysql/query.log 2、增加目录和文件&#xff0c;并且授权 可以使用以下命令修改权限&#xff1a; 创建目录&#xff1a;sudo mkdir -p /var/log/mysql 更改目录所有者&#xff1a;sudo…

okcc呼叫中心系统如何对客户进行按键标记?呼叫系统搭建

要在OKCC呼叫中心系统中对客户进行按键标记&#xff0c;可以按照以下步骤操作&#xff1a; 登录系统&#xff1a;首先&#xff0c;使用管理员或具有相应权限的账户登录OKCC呼叫中心系统。 搜索客户&#xff1a;在系统的主界面或客户管理界面&#xff0c;通过搜索功能找到需要标…

【日常记录】【插件】prisma 链接MySQL数据库 简单入门

文章目录 1、新建项目&#xff0c;使用prisma链接数据库1.1、先创建一个项目1.2、初始化 npm 配置文件及下载依赖1.3、初始化TS配置文件1.4、初始化 prisma1.5、更改 prisma/schema.prisma1.6 更改.env 文件1.7 编写 prisma/schema.prisma1.8 将编写的 prisma/schema.prisma 映…

OSPF被动接口配置(华为)

#交换设备 OSPF被动接口配置 一、基本概念 OSPF被动接口&#xff0c;也称为抑制接口&#xff0c;即将路由器某一接口配置为被动接口后&#xff0c;该接口不会再接受和发送OSPF报文 二、使用场景 在路由器与终端相近或者直接相连的一侧配置被动接口 因为OSPF会定期发送报文…

ensp防火墙web密码重置(前提通过console可以登录)

客户电脑是命令行没有用户名直接输入密码就可以登录了&#xff0c;但是web端不知道admin的密码 前两天遇到运维单位的一台防火墙web网页不知道用户名密码&#xff0c;默认的登录不了&#xff0c;但是通过console可以登录命令行&#xff0c;今天就记录下如何通过命令行修改web页…