javahttp接口实现原理的简单介绍

java如何实现http长连接

通过轮询来实现长连接

轮询:隔一段时间访问服务器,服务器不管有没有新消息都立刻返回。

http长连接实现代码:

客户端:

package houlei.csdn.keepalive;

import java.io.IOException;

import java.io.InputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.Socket;

import java.net.UnknownHostException;

import java.util.concurrent.ConcurrentHashMap;

/**

*C/S架构的客户端对象,持有该对象,可以随时向服务端发送消息。

* p

* 创建时间:2010-7-18 上午12:17:25

* @author HouLei

* @since 1.0

*/

public class Client {

/**

* 处理服务端发回的对象,可实现该接口

*/

public static interface ObjectAction{

void doAction(Object obj,Client client);

}

public static final class DefaultObjectAction implements ObjectAction{

public void doAction(Object obj,Client client) {

System.out.println(“处理:\t”+obj.toString());//诊断程序是否正常

}

}

public static void main(String[] args) throws UnknownHostException, IOException {

String serverIp = “127.0.0.1”;

int port = 65432;

Client client = new Client(serverIp,port);

client.start();

}

private String serverIp;

private int port;

private Socket socket;

private boolean running=false;

private long lastSendTime;

private ConcurrentHashMapClass, ObjectAction actionMapping = new ConcurrentHashMapClass,ObjectAction();

public Client(String serverIp, int port) {

this.serverIp=serverIp;this.port=port;

}

public void start() throws UnknownHostException, IOException {

if(running)return;

socket = new Socket(serverIp,port);

System.out.println(“本地端口:”+socket.getLocalPort());

lastSendTime=System.currentTimeMillis();

running=true;

new Thread(new KeepAliveWatchDog()).start();

new Thread(new ReceiveWatchDog()).start();

}

public void stop(){

if(running)running=false;

}

/**

* 添加接收对象的处理对象。

* @param cls 待处理的对象,其所属的类。

* @param action 处理过程对象。

*/

public void addActionMap(ClassObject cls,ObjectAction action){

actionMapping.put(cls, action);

}

public void sendObject(Object obj) throws IOException {

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

oos.writeObject(obj);

System.out.println(“发送:\t”+obj);

oos.flush();

}

class KeepAliveWatchDog implements Runnable{

long checkDelay = 10;

long keepAliveDelay = 2000;

public void run() {

while(running){

if(System.currentTimeMillis()-lastSendTimekeepAliveDelay){

try {

Client.this.sendObject(new KeepAlive());

} catch (IOException e) {

e.printStackTrace();

Client.this.stop();

}

lastSendTime = System.currentTimeMillis();

}else{

try {

Thread.sleep(checkDelay);

} catch (InterruptedException e) {

e.printStackTrace();

Client.this.stop();

}

}

}

}

}

class ReceiveWatchDog implements Runnable{

public void run() {

while(running){

try {

InputStream in = socket.getInputStream();

if(in.available()0){

ObjectInputStream ois = new ObjectInputStream(in);

Object obj = ois.readObject();

System.out.println(“接收:\t”+obj);//接受数据

ObjectAction oa = actionMapping.get(obj.getClass());

oa = oa==null?new DefaultObjectAction():oa;

oa.doAction(obj, Client.this);

}else{

Thread.sleep(10);

}

} catch (Exception e) {

e.printStackTrace();

Client.this.stop();

}

}

}

}

}

服务端:

package houlei.csdn.keepalive;

import java.io.IOException;

import java.io.InputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ConcurrentHashMap;

/**

* C/S架构的服务端对象。

* p

* 创建时间:2010-7-18 上午12:17:37

* @author HouLei

* @since 1.0

*/

public class Server {

/**

* 要处理客户端发来的对象,并返回一个对象,可实现该接口。

*/

public interface ObjectAction{

Object doAction(Object rev);

}

public static final class DefaultObjectAction implements ObjectAction{

public Object doAction(Object rev) {

System.out.println(“处理并返回:”+rev);//确认长连接状况

return rev;

}

}

public static void main(String[] args) {

int port = 65432;

Server server = new Server(port);

server.start();

}

private int port;

private volatile boolean running=false;

private long receiveTimeDelay=3000;

private ConcurrentHashMapClass, ObjectAction actionMapping = new ConcurrentHashMapClass,ObjectAction();

private Thread connWatchDog;

public Server(int port) {

this.port = port;

}

public void start(){

if(running)return;

running=true;

connWatchDog = new Thread(new ConnWatchDog());

connWatchDog.start();

}

@SuppressWarnings(“deprecation”)

public void stop(){

if(running)running=false;

if(connWatchDog!=null)connWatchDog.stop();

}

public void addActionMap(ClassObject cls,ObjectAction action){

actionMapping.put(cls, action);

}

class ConnWatchDog implements Runnable{

public void run(){

try {

ServerSocket ss = new ServerSocket(port,5);

while(running){

Socket s = ss.accept();

new Thread(new SocketAction(s)).start();

}

} catch (IOException e) {

e.printStackTrace();

Server.this.stop();

}

}

}

class SocketAction implements Runnable{

Socket s;

boolean run=true;

long lastReceiveTime = System.currentTimeMillis();

public SocketAction(Socket s) {

this.s = s;

}

public void run() {

while(running run){

if(System.currentTimeMillis()-lastReceiveTimereceiveTimeDelay){

overThis();

}else{

try {

InputStream in = s.getInputStream();

if(in.available()0){

ObjectInputStream ois = new ObjectInputStream(in);

Object obj = ois.readObject();

lastReceiveTime = System.currentTimeMillis();

System.out.println(“接收:\t”+obj);

ObjectAction oa = actionMapping.get(obj.getClass());

oa = oa==null?new DefaultObjectAction():oa;

Object out = oa.doAction(obj);

if(out!=null){

ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

oos.writeObject(out);

oos.flush();

}

}else{

Thread.sleep(10);

}

} catch (Exception e) {

e.printStackTrace();

overThis();

}

}

}

}

private void overThis() {

if(run)run=false;

if(s!=null){

try {

s.close();

} catch (IOException e) {

e.printStackTrace();

}

}

System.out.println(“关闭:”+s.getRemoteSocketAddress());//关闭长连接

}

}

}

长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的。

如果,长时间未发送维持连接包,服务端程序将断开连接。

javahttp接口实现原理的简单介绍

JAVA程序的底层是如何调用http协议通讯?是不是调用操作系统的接口?高手谢谢

http是一种协议,如果我们要在使用http协议的网络上进行数据传输,就必须遵循这种协议规则。

java可以用socket进行数据传输,但是数据的格式必须遵循http协议。

也可以使用封装好的类例如URLConnection,或者HttpURLConnection。

数据最终要通过网卡发送出去,所以要调用系统驱动发送,但是这些应该是JVM去实现的,因为java是跨平台的,java字节码与操作系统之间有个桥梁就是JVM,而不同的操作系统对应不同的JVM,但是这些JVM都可以用于解析字节码,调用底层硬件实现功能。

java中httpSession这个接口具体的实现在哪啊?不是接口不能被实例化对象的吗?

JAVA特性的一个: 多态

好处很多啊: 最大的好处就是 不改代码,灵活赋值

比如: 接口A 下在有 实现类 B,C,D

那你只要一个 接口A的变量 就可以接收 new B(), new C(); new D();

并且调用实现类从接口 实现来的方法, 三个实现类你把哪个的实现赋值给接口变量,这个接口变量就能调用哪 个实现类的方法

网络请求框架-OkHttp原理解析

okhttp是square公司贡献的一个处理网络请求的开源框架,是目前Android开发使用最广泛的一个网络框架,从Android4.4开始,httpURLconnection的底层实现采用的就是okhttp。内部实现就是利用java基础,对socket进行封装,实现http通信。最重要的两个关键点就是分发器和5个拦截器。

分发器 就是内部维护队列和线程池,完成请求分配,总结就是用于对异步任务加入队列管理,然后判断条件,控制数量,加入线程池执行异步请求任务。

五个默认拦截器 就是利用责任链模式对网络请求进行层层处理,完成整个请求过程,简单总结如下。

1.桥接拦截器对用户发出的请求添加缺少的请求配置字段,比如keep-alive等

2.缓存拦截器就是查询有没有符合判断条件的已缓存的网络请求,执行复用,直接返回response

3.连接拦截器就是创建请求,加入连接器 或者访问连接池,根据条件判断,是否能怼已创建的tcp请求进行复用

4.请求服务器拦截器就是对scoket进行操作,请求网络访问服务器,返回response,

5.重试和重定向拦截器就是对返回的response进行code判断,决定是否要重试或者重定向操作。

1.支持http2.0版本,并且允许对同一主机的所有请求共享一个套接字

2.即使不是http2.0版本,通过连接池,减少请求延迟

3.默认使用Gzip 压缩数据

4.响应缓存,避免重复请求网络

最简单的http请求案例

1.利用建造者模式构建okHttpClient实例对象,构建过程中可以动态配置参数,请求时间,响应时间,缓存信息等。

2.创建Request对象,设置请求方式,链接地址,参数等信息。

3.把request对象,传给client,通过newCall函数,得到RealCall对象。

4.RealCall 分为同步和异步执行

5.同步执行时,分发器只是做个记录,把请求任务加到队列中,然后直接通过拦截器访问服务器,返回response。

6.异步执行

6.1先对异步任务进一步封装,把任务放到AsyncCall对象中

2.分发器 把 封装后的异步任务 添加到等待运行的队列中

7.getResponseWithInterceptorChain 通过拦截器,获取response

okhttp 默认提供5个拦截器 重试重定向拦截器,桥接拦截器,缓存拦截器,连接拦截器,访问服务器拦截器。还可以自定义拦截器。

自定义拦截器分为应用拦截器(通过addInterceptor 添加)和网络拦截器(通过addNetworkInterceptor拦截)

拦截器采用责任链的设计默认,让请求者和处理者解耦,最终请求从前往后,响应从后往前。

首先先判断用户是否取消了请求,如果没有取消,就把请求交个桥接拦截器。

在获得响应结果response的时候根据响应码,判断是否需要重试或者重定向, 重试不限制次数,重定向最多20次 ,如果需要重试或者重定向,那么会再一次重新执行所有拦截器。

有如下几种情况不会重试:IO异常,线路异常,配置client实例时配置不允许重试,协议异常,证书异常等等。

先获取用户发送的请求,判断条件用户是否已经配置过请求头字段,若用户没有配置,则将http协议必备的请求头字段补齐,比如Content-Type,Content-Length等,然后交给下一个拦截器。

在获得响应结果response之后,调用保存cookie的接口(也可以在配置client的时候,设置cookjar进行cookie回调数据),并且解析gzip数据

获取结果之后,对cookie进行保存,对返回的数据进行gzip解压

就是根据缓存策略从缓存中查找是否有合适的缓存response,如果有合适的缓存,直接返回给请求任务,不在继续执行后面的拦截器。

获得响应结果response后,根据条件判断,决定是否要缓存。

维护一个连接池,负责对连接的服务。在把请求交给下一个拦截器之前。会先在连接池中找到一个合适的连接(满足适配条件相同,并且没有正在被使用)或者新建一个连接,并且接入连接池,获得对应的socket流,把请求交给下一个拦截器。获得response结果后不会进行额外的处理。

连接池, 也称之为对象池,主要用来存放request请求连接,内部维护了一个LinkedQueue队列用来存放请求。在添加新的请求对象时,都会执行一个周期性任务,用以对连接池进行清理操作。

1.队列长度超过5,清理最近未被使用连接,LRE算法

2.存储的连接,5分钟未被复用,清理

拿到上一个拦截器返回的请求,真正的与服务器进行通信,向服务器发送数据,解析读取响应的数据,返回给上一个拦截器。

1.创建request =OkHttpClient=RealCall()

2.同步执行 ,分发器添加同步任务,执行拦截器,访问服务器,返回reponse,触发异步分发流程。

3.异步执行 ,封装任务= AsyncCall ,实现runnable接口。添加任务到异步任务等待队列,执行分发任务,判断异步任务是否能加入正在执行的异步任务队列,满足两个条件

同时执行的异步任务数量不得大于64个

对同一个主机的访问任务,最多不得大于5个

4.加入正在执行的异步任务队列,通过线程池执行任务,经过5个默认拦截器访问服务器,返回response,执行异步任务分发。

分发器工作 分为同步任务和异步任务两种

同步任务 就是把任务加入同步任务队列,加个标记,执行结束之后,触发异步任务的分发操作。

异步任务 先封装任务到asyncCall对象,实现了runnable接口。把任务加入等待执行队列,执行分发操作。

先遍历等待任务队列,判断是否符合加入正在运行的异步任务队列,要同时满足两个条件。

同时执行的异步任务数量不得大于64个

对同一个主机的访问任务,最多不得大于5个

当满足条件后,从等待队列中删除任务,把任务加入正在执行的队列中,通过自定义的线程池,执行任务,任务执行结束后,再次执行分发操作。

拦截器采用了责任链设计默认,让请求者和执行者解耦,请求者只需要将请求发给责任链即可,无需关心请求过程和细节。okHttp 默认有5个拦截器,重试重定向拦截器,桥接拦截器,缓存拦截器,连接拦截器,请求服务拦截器。工作细节参考上面拦截器原理分析部分

1.位置的关系,应用拦截器 放在责任链最顶端,网络拦截器放在责任链倒数第二的位置。所以应用拦截器 最先拦截,最后响应,网络拦截器 倒数第二拦截,第二响应。如果打印请求日志的情况,应用拦截器打印的是用户请求信息,经过重试重定向,桥接,缓存,链接 等拦截器的层层包装,网络拦截器打印的是实际请求的信息。

2.应用拦截器一定会被执行,网络拦截器不一定被执行。

利用连接池,缓存所有的有效连接对象。

清理机制:垃圾连接

1.超过5分钟没有用过的链接

2.超过5个闲置链接后,从最久闲置的链接开始执行清理(LRU)

北大青鸟java培训:http协议请求处理过程?

随着互联网的不断发展,用户在访问互联网的时候使用的终端设备类型也在不断的变化,但是这些都是基于http协议来实现的,下面我们就简单分析一下,http发送请求的处理过程。

HTTP协议是基于TCP协议的,所以它使用面向连接的方式发送请求,通过stream二进制流的方式传给对方。

当然,到了TCP层,它会把二进制流变成一个的报文段发送给服务器。

在发送给每个报文段的时候,都需要对方有一个回应ACK,来保证报文可靠地到达了对方。

如果没有回应,那么TCP这一层会进行重新传输,直到可以到达。

同一个包有可能被传了好多次,但是HTTP这一层不需要知道这一点,因为是TCP这一层在埋头苦干。

TCP层发送每一个报文的时候,都需要加上自己的地址(即源地址)和它想要去的地方(即目标地址),将这两个信息放到IP头里面,交给IP层进行传输。

IP层需要查看目标地址和自己是否是在同一个局域网。

如果是,就发送ARP协议来请求这个目标地址对应的MAC地址,然后将源MAC和目标MAC放入MAC头,发送出去即可。

如果不在同一个局域网,就需要发送到网关,还要需要发送ARP协议,来获取网关的MAC地址,然后将源MAC和网关MAC放入MAC头,发送出去。

网关收到包发现MAC符合,取出目标IP地址,根据路由协议找到下一跳的路由器,获取下一跳路由器的MAC地址,将包发给下一跳路由器。

这样路由器一跳一跳终于到达目标的局域网。

这个时候,后一跳的路由器能够发现,目标地址就在自己的某一个出口的局域网上。

于是,在这个局域网上发送ARP,获得这个目标地址的MAC地址,将包发出去。

目标的机器发现MAC地址符合,就将包收起来;发现IP地址符合,根据IP头中协议项,知道自己上一层是TCP协议,于是解析TCP的头,里面有序列号,IT培训建议需要看一看这个序列包是不是我要的,如果是就放入缓存中然后返回一个ACK,如果不是就丢弃。

TCP头里面还有端口号,HTTP的服务器正在监听这个端口号。

于是,目标机器自然知道是HTTP服务器这个进程想要这个包,于是将包发给HTTP服务器。

HTTP服务器的进程看到,原来这个请求是要访问一个网页,于是就把这个网页发给客户端。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月25日 08:44:29
下一篇 2024年3月25日 08:51:54

相关推荐

  • c语言mallloc使用的简单介绍

    C语言中使用malloc必须加#includemallo.h? 1、在C语言中使用malloc函数进行动态内存分配。malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void malloc(unsigned int num_bytes);功能:分配长度为num_bytes字节的内存块。 2、你可以看一下C语言那本…

    2024年5月23日
    4400
  • javascriptcanvas的简单介绍

    如何使用js在画布上绘制图形 1、可以使用 drawImage()方法把一幅图像绘制到画布上。 以使用三种不同的参数组合。最简单的调用方式是传入一个 HTML 元素,以及绘制该图像的起点的 x 和 y 坐标。 2、效果图:使用JavaScript在画布中绘制文本图形首先我们来看看要在画布上绘制文本图形,需要用到的最重要的属性和方法:font属性:定义文本的字…

    2024年5月23日
    4200
  • cortexm4linux的简单介绍

    Cortex-M4的主要功能 Cortex-M4提供了无可比拟的功能,以将[1] 32位控制与领先的数字信号处理技术集成来满足需要很高能效级别的市场。 Cortex-M4核心具有浮点单元(FPU)单精度,支持所有Arm单精度数据处理指令和数据类型。它还实现了一套完整的DSP指令和一个提高应用程序安全性的内存保护单元(MPU)。 主要是m4比m3多了dsp的支…

    2024年5月23日
    4300
  • 3desjavaphp的简单介绍

    php的3des加密结果与java不一致 他们的加密算法都是通用的,是可以解开的,只要你des的模式,加密长度,初始向量什么的都一样就可以。 JAVA写RSA加密,私钥都是一样的,公钥每次加密的结果不一样跟对数据的padding(填充)有关。Padding(填充)属性定义元素边框与元素内容之间的空间。padding简写属性在一个声明中设置所有内边距属性。 要…

    2024年5月23日
    4700
  • 黑客代码软件学习推荐歌曲的简单介绍

    我想自学编程代码,,目地是“黑”网站,开发出破解代码。有没有这方面的… 这个迭代周期不应该以周为周期或以月为周期发生,而是应该以日为周期。知识等待使用的时间越久,知识这把斧头就越钝。等待学习新知识的时间越长,你就越难以将其融入到代码中。 我认为这个问题问得本身就显得有点矛盾,想学却担心自己看不懂代码学不来,试问哪个编程人员不是从零开始的。坚定信念…

    2024年5月23日
    4700
  • java8种基本类型范围的简单介绍

    java中常用的数据类型有哪些 1、java数据类型分为基本数据类型和引用数据类型,基本数据类型有boolean 、long 、int 、char、byte、short、double、float。引用数据类型有类类型、接口类型和数组类型。 2、java中包含的基本数据类型介绍:\x0d\x0aJava共支持8种内置数据类型。内置类型由Java语言预先定义好,…

    2024年5月23日
    4600
  • linux系统与gpt的关系的简单介绍

    linux下查看分区是不是gpt 看分区会报错,比如:WARNING: GPT (GUID Partition Table) detected on /dev/sda! The util fdisk doesnt support GPT. Use GNU Parted.所以这个sda就是gpt的。 选择“管理”;在“磁盘管理”中,右键“磁盘0”,在弹出的右键…

    2024年5月23日
    5300
  • 北京黑客学习培训的简单介绍

    现在学什么好啊 包括建筑设计、服装设计、珠宝首饰设计等,选择适合自己的设计专业,好好学习,就业容易且收入高。学前教育专业:很多女生喜欢小孩子,且女生一般细心且有耐心,教育行业假期宽裕,工作环境单纯,就业机会多。 现在比较热门好就业的专业有人工智能、机械专业、电子商务专业、人力资源专业、金融学专业、小语种类专业等等。人工智能:人工智能领域的研究包括机器人、语言…

    2024年5月23日
    4000
  • javaee要学那些东西的简单介绍

    java主要学习哪些内容 1、学java最重要的是下面四个内容:掌握Java语言的使用:语言语法、程序逻辑,OOP(面向对象)思想,封装、继承、多态,集合框架、泛型、File I\O技术,多线程技术、socket网络编程,XML技术。 2、Java基础:了解Java的基本语法、数据类型、控制流程、数组、字符串等基础概念。学习面向对象编程(OOP)的原则和概念…

    2024年5月23日
    4100
  • excel自杀的简单介绍

    excel表格中宏代码,具有自杀功能,密码输入错误3次就自动删除表格_百度… 我给楼主一个建议,利用excel自身的密码保护,保护此工作簿的结构,将sheet提前隐藏。这样如果有人将同一份excel打开时,如果不能输入正确的密码,就不能将sheet取消隐藏,就能达到楼主所说的保护了。 如果你还有源文件的话,可以这样试试:打开其他的excel文件,…

    2024年5月23日
    8100

发表回复

登录后才能评论



关注微信