一、概述

最近想尝试写一个关于网络请求的系列文章,将网络请求的基础、使用及网络框架的学习分析总结以下,大致准备从以下几个方面分析:

  1. 网络请求的基础
  2. HTTP请求方式和报文解析
  3. Cookie 和 Session的理解与使用
  4. HTTP Cache缓存机制
  5. 封装网络请求
  6. TCP 和 Socket

二、HTTP请求方式

HTTP提供了七种请求方式:GET、POST、DELETE、PUT、HEAD、TRACE、OPTIONS,其中PUT,DELETE、POST、GET分别对应了资源的增、删、改、查,也是使用最多的请求方式;

  • GET
  1. GET请求报文 和 服务器的响应报文

    

上述请求的资源是www.devtf.cn/articles/123.html文件,GET请求是将请求参数放在URL之后,第一个参数之前使用““,之后的参数格式为:参数名=参数值,参数名之间使用”&“连接,如:www.devtf.cn/articles/123.html?username=myname&userid=123

  • POST

POST请求通常是使用来提交HTML的表单,表单中的数据传输到服务器,由服务器对这些数据处理,请求和响应的报文如下:

  • PUT

与GET从服务器获取数据相反的是,PUT是想服务器写入资源,比如像CSDN这样允许用户创建Web页面,并用PUT直接传输到服务器上,返回服务器上的资源地址;

  • DELETE

使用方法和GET一样,请求删除URL指定的资源文件

三、HTTP请求报文

HTTP的请求报文由请求行(Request line)、请求头部(Header)空行和请求数据;

  1. 请求行:请求报文的第一行,用来说明以什么方式请求、请求的地址和HTTP版本
  2. 头部字段:每个头部字段都包含一个名字和值,二者之间采用“:”连接,如:Connection:Keep-Alive
  3. 请求数据:请求的主体根据不同的请求方式请求主体不同
  • GET、DELETE

这两种请求报文比较简单,查看上面即可

  • POST、PUT

POST和PUT的请求行和请求头部,在上述已经列出,现在主要介绍请求报文中的参数:

  1. 一个参数的开始是由“--”加上boundary开始的
  2. 然后加上参数的Header信息,格式为字段名和字段值,二者之间使用“:”连接,如:Content-Type:text/plain
  3. 加上一个空行
  4. 发送的参数值
  5. 请求的数据以“--”+boundary+“--”结束真个请求的报文结束符

四、HTTP响应报文

HTTP的响应报文为3个部分组成:状态行、消息报文、响应正文

  1. 状态行:由HTTP版本、响应状态码、响应状态描述;如:HTTP/1.1 200 OK
  2. 响应报文头部:使用关键字和值表示,二者使用“:”隔开;如:Content-Type:text/html
  3. 响应内容:请求空行之后就是请求内容
  • 常见的状态码和描述
  1. 200  OK : 客户端请求成功
  2. 400  Bad Request:客户端请求语法错误,服务器无法解析
  3. 401  Unauthorized:请求未经授权
  4. 403  Forbidden:服务器收到请求拒绝服务
  5. 404  Not Found:请求资源不存在,常见URL错误
  6. 500  Internal Server Error:服务端不可预期错误
  7. 503  Server Unavailable:服务器当前不能处理客户端请求

五、简单模拟HTTP服务器

  • 创建HttpServer:内部创建ServerSocket监听客户端的输出信息
public const val HTTP_PORT = 8080  // 监听的端口
class HttpServiceSocket : Thread() {val mServiceSocket by lazy {ServerSocket(HTTP_PORT)   // 创建ServerSocket}override fun run() {while (true){Log.d("HttpServiceSocket","Service 等待输入...")DeliverThread(mServiceSocket.accept()).start() //开启线程接收信息}}
  • 为了不阻塞线程,再开辟新线程从输入流中读取数据
class DeliverThread(val socket: Socket) : Thread() {val bufferedReader by lazy {BufferedReader(InputStreamReader(socket.getInputStream()))}val printStream by lazy {PrintStream(socket.getOutputStream())}val headerParamsMap = mutableMapOf<String,String>() // 储存Header的参数信息val paramsMap = mutableMapOf<String,String>() // 储存参数的参数信息lateinit var httpMethod : Stringlateinit var subPath : Stringlateinit var boundary : Stringvar isParseHeader = falseoverride fun run() {super.run()parseRequest() // 解析RequesthandlerResult()  // 构建返回的ResponsebufferedReader.close()printStream.close()socket.close()}
}
  • 解析Request:parseRequest()
 private fun parseRequest() {var line = 1var lineString : String? = bufferedReader.readLine()while (lineString != null){if (line == 1){parseRequestLine(lineString)// 解析请求行}if (line != 1 && !isParseHeader){parserHeader(lineString)  // 解析请求头部}if (isParseHeader){parseParams(lineString) // 解析参数}lineString = bufferedReader.readLine()  //循环读取数据line++}}
  • 解析请求行、请求头部、请求参数
// 解析请求行private fun parseRequestLine(lineString: String) {val strings = lineString.split(" ")Log.d("Http Method",strings[0])Log.d("Http Path",strings[1])Log.d("Http Version",strings[2])}// 解析请求头部private fun parserHeader(lineString: String) {if (lineString == ""){isParseHeader = trueLog.d("Http Request","-------Header 解析完成 -------")return}else if (lineString.contains("boundary")){boundary = parseBoundary(lineString)Log.d("Http Request","boundary=$boundary")}else{val strings = lineString.split(":")headerParamsMap[strings[0]] = strings[1]Log.d("Http Content","${strings[0] .trim()}  :  ${strings[1] .trim()}")}}private fun parseBoundary(lineString: String): String {val strings = lineString.split(";")parserHeader(strings[0])if (strings[1] != null){return strings[1].split("=")[1]}return ""}private fun parseParams(lineString: String) {if (lineString == "--$boundary"){Log.d("Http Content",lineString)parseParamsType()}}private fun parseParamsType() {val stringParams = bufferedReader.readLine()Log.d("Http Content",stringParams)val name = parseBoundary(stringParams)bufferedReader.readLine()val value = bufferedReader.readLine()paramsMap[name] = valueLog.d("Http Content"," ")Log.d("Http Content","$value")}
  • 模拟POST请求
class HttpPost(var url:String)  {private lateinit var mSocket: Socket  // 创建Socketval  paramsMap = mutableMapOf<String,String>()  // 储存设置的信息fun add(name : String, value : String){  // 添加参数paramsMap[name] = value}fun execute(){mSocket = Socket(url, HTTP_PORT)val printStream = PrintStream(mSocket.getOutputStream())val bufferedReader = BufferedReader(InputStreamReader(mSocket.getInputStream()))val boundary = "http_boundary_123"writeHead(boundary,printStream)writeParams(boundary,printStream)writeResponse(bufferedReader)}// 输出返回的Responseprivate fun writeResponse(bufferedReader: BufferedReader) {Log.d("Http Response","请求结果...")Thread{var string = bufferedReader.readLine()while (string == null || !string.contains("HTTP")){string = bufferedReader.readLine()}while (string != null){Log.d("Http Response",string)string = bufferedReader.readLine()}}.start()}// 写入参数private fun writeParams(boundary: String, printStream: PrintStream) {var iterator = paramsMap.keys.iterator()while (iterator.hasNext()){val name = iterator.next()printStream.println("--$boundary")printStream.println("Content-Disposition: from-data; name=$name")printStream.println()printStream.println(paramsMap.get(name))}printStream.println("--$boundary--")}
//写入请求头部private fun writeHead(boundary: String, printStream: PrintStream) {printStream.println("POST /api/login/ HTTP/1.1")printStream.println("content-length:123")printStream.println("Host:$url:$HTTP_PORT")printStream.println("Content-Type:multipart/from-data;boundary=$boundary")printStream.println("User-Agent:android")printStream.println()}
}
  • 启动ServerSocket并发送请求信息
btnService.setOnClickListener { HttpServiceSocket().start() }btnPost.setOnClickListener {Thread {val httpPost = HttpPost("127.0.0.1")httpPost.add("userName","Simple")httpPost.add("pwd","pwd_123")httpPost.execute()}.start()}
  • 运行后输出信息

HTTP请求方式和报文解析相关推荐

  1. get 和 post 请求方式 及其参数解析

    一.Get与Post区别   Get和Post都是Http协议的组件,所以底层都是使用tcp链接.Get的请求方式是将http的header和data一并发往服务端,也就是一条tcp数据包发送,这就会 ...

  2. WebService soap报文请求与响应报文解析

    需求 今日公司要做一个协同办公系统(OA),PC端已经完成.现在要做一个手机端网页端的.从登陆入手,需要向 服务端发送一段请求报文获取响应报文,对响应报文进行解析判断是否登录成功. 当然手机客户端发送 ...

  3. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...

  4. 航信电子发票开发(servlet请求方式)

    在系统用户交费后,需要打印发票,可以选择普票或者机打票(票据信息在系统中自定义设置的),也可以打印电子发票,这里对接的是航信的电子发票,请求方式非web服务,而是使用servlet通过HTTP请求的方 ...

  5. 支付系统设计三:渠道网关设计02-客户端报文解析

    文章目录 前言 一.后台配置管理 1.1 渠道配置 1.1.1 渠道基本信息新增 1.1.2 渠道交易类型配置 1.1.3 渠道商户信息配置 1.1.4 账户配置 1.1.5 交易类型机构配置 1.2 ...

  6. http协议与https协议+UDP协议和TCP协议+WebSocket协议下服务端主动去发送信息+对称加密与非对称加密+get和post请求方式区别详解+浏览器内核以及jsj解析引擎

    TCP和UDP协议是TCP/IP协议的核心. 在TCP/IP网络体系结构中,TCP(传输控制协议,Transport Control Protocol).UDP(用户数据报协议,User Data P ...

  7. html解析 英文,http请求报文解析(国外英文资料).doc

    http请求报文解析(国外英文资料) http请求报文解析(国外英文资料) HTTP request message sample: POST/pass/demo/requesttest.jsp HT ...

  8. axios post json_助你解析Axios原理之一:如何实现多种请求方式

    自从Axios成功打入Vue全家桶之后,便开始火的一塌糊涂!截止到目前,其在github上的star即将突破80k!可以说Axios是当下前端界最流行的ajax请求库,可(jue)能(dui)没有之一 ...

  9. HTTP的8种请求方式及常用请求方式的解析

    一.什么是HTTP? HTTP,即超文本传输协议,是一种实现客户端和服务器之间通信的响应协议,它是用作客户端和服务器之间的请求. 客户端(浏览器)会向服务器提交HTTP请求:然后服务器向客户端返回响应 ...

最新文章

  1. CTOR在区块熵编码中的优点
  2. 机器学习梯度下降法举例
  3. java获取系统电量_android操作系统怎么获得电量
  4. C++继承中的普通函数,纯虚函数、虚函数
  5. 【python】set集合基础与使用
  6. 支付业务与技术架构学习总结(8)——支付系统设计包含:账户,对账,风控...
  7. 未来5年中国企业信息化格局
  8. NOIP 2014 解方程
  9. 「收藏」其实是欺骗自己
  10. 《我一开口,就能说服所有人》读书随记
  11. 使用数字全通滤波器对IIR滤波器进行相位补偿
  12. SRCNN 图像超分辨率重建(tf2)
  13. 【数据库系统】、【数据库】与【数据库管理系统】的区别
  14. 我是怎么做到开源系统中的文件上传等功能的?
  15. mpvue 搭配 minui
  16. [机器学习] 树模型(xgboost,lightgbm)特征重要性原理总结
  17. 软件测试工程师简历要怎么写,才能让 HR 看到?
  18. 日本测试人工智能破案,“机械战警”渐行渐近
  19. 视频按帧截取 python程序
  20. iTab!一款超级无敌好用的浏览器插件 简洁美观

热门文章

  1. Keil uVision5修改工程名字
  2. 苹果企业账号申请记录
  3. outlook 2013 配置163企业邮箱
  4. USB协议分析仪在实际USB连通中的作用
  5. 关于找不到java.dll 解决方案
  6. 手把手实现WebRTC音视频通话
  7. python爬取有道词典json报错,求帮助!
  8. 多阶段决策问题——DAG(算法竞赛入门经典笔记)
  9. 毒霸07.11.19.18版本 新增加922个查杀病毒
  10. 如何在Mac或PC上使用“查找我的iPhone