Socket与HTTP解析

Posted study_zhxu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket与HTTP解析相关的知识,希望对你有一定的参考价值。

1.网络基础

网络分层:计算机网络分层模型有两种

  • OSI参考模型
  • TCP/IP参考模型

网络层:根据IP查找到目的地址的主机

运输层:通过端口把数据发送给目的主机,实现进程间通信

2.端口

端口规定有16位,及计算机有2的16次方65536个端口。

3.C/S架构

定义:即客户端/服务端,软件体系架构

作用:利用客户端和服务端的硬件资源,将任务合理的分配到客户端和服务端来实现,降低开销

Socket套接字就是这种软件架构,套接字客户端和套接字服务器

Socket的使用基于TCP和UDP协议

4.TCP协议

定义:TCP协议即传输控制协议,是一种传输层通信协议
特点:面向连接、可靠、全双工通信、面向字节流

  • 面向连接:是指TCP传输数据时双方必须建立连接,传输完成时必须释放连接
  • 可靠:是指,传输的数据无差错、不丢失、不重复、按顺序到达
  • 全双工通信:是指只要建立连接成功后,在之后任何时候都可发送数据
  • 面向字节流:流指的是流入进程或者从进程流出的字符序列。当TCP传输的数据过大时,TCP报文长度有限,所以或将其分割成几个数据块传输,但是因为有可靠性的保证,所以接收方会按顺序收到数据块然后将其组装成完整的数据。所以看起来像是TCP传输的是字节流一样。

5.TCP三次握手连接

TCP客户端和服务端连接需要经过三次握手才可以

  • 第一次握手:客户端A向服务端B发送连接请求,将SYN的值置为1,同时随机产生seq的值x,然后客户端进入SYN_SEND状态
  • 第二次握手:服务端B收到请求后,通过SYN=1知道客户端想连接,然后服务端B向客户端A发送确认连接,发送SYN=1,ACK=1,ack=x+1(第一次握手的seq值+1),seq=y(随机产生seq的值),然后服务端B进入到SYN_RCVD状态
  • 第三次握手:客户端A收到服务端B发送的确认消息后,检验ACK是否为1,ack是否是第一次握手是发送的seq值+1,如果验证通过,则向服务端B发送确认信息ACK=1,ack=y+1,seq=x+1。然后客户端A进入ESTABLISHED状态。服务端收到后确认信息是否正确,如果正确进入ESTABLISHED状态。

完成三次握手后,接下来可以在任何时刻发送和接收数据

三次握手中的任何一次没有成功,都要重新发送

为什么要三次握手:

1.在连接时可能会出现这样的情况,客户端发送了连接请求,但是该信息在某个网络节点滞留时间过长,客户端已经连接超时释放了该连接后,该连接请求到达服务端后

2.该信息其实是一个过时失效的信息,所以当服务端收到信息后,以为客户端需要建立连接,于是服务端会向客户端发送确认信息。

3.如果没有采用三次握手,就会出现服务端认为是连接并且建立连接,等待客户端发送数据,但是客户端并没有要求建立连接,是不会向服务端发送数据的,所以服务端就会白白的等待客户端发送数据,这样就浪费了服务端的资源。

6.TCP释放连接

TCP释放连接时需要四次挥手过程(数据传输完成后,双方都可以释放连接)

  • 第一次挥手:主机1向主机2发起释放连接请求FIN=1,seq=u,主机1进入FIN_WAIT-1状态
  • 第二次挥手:主机2收到主机1的释放请求后,回复确认释放信息ACK=1,ack=u+1,seq=v,主机2进入CLOSE_WAIT状态
  • 第三次挥手:然后主机2向主机1发送释放连接请求FIN=1,ACK=1,seq=w,ack=u+1,主机2进入LAST_ACK状态
  • 第四次挥手:主机1收到主机2的释放请求后进入,向主机2发送确认信息ACK=1,ack=w+1,seq=u+1,主机1进入TIME_WAIT状态

主机2收到确认信息后会释放连接

主机1等待2MSL(最大报文生存时间)后,没有收到主机2的信息证明主机2已经释放了连接,然后主机1释放连接

为什么需要四次挥手

为了确保双方都能释放连接

因为TCP是全双工通信的,所以客户端和服务端都可以发送和接收数据

1.第一次挥手:告诉主机2,主机1没有数据需要发送了或数据已全部发送完毕,但是此时主机1还是可以收到主机2发送的消息

2.第二次挥手:主机2发送确认释放连接信息,此时主机2知道主机1没有数据发送了,但是主机2还可以发送数据

3.第三次挥手:主机2向主机1发送释放连接信息,告诉主机1,主机2也没有数据发送了。此时主机1和主机2都没有数据发送。

4.第四次挥手:主机1知道了主机2也没有数据发送了,向主机2发送确认释放连接信息。此时连接释放完成

为什么需要等到2MSL(最大报文生存的时间)后才进入CLOSE状态

  • 1.保证TCP的双全工连接能够可靠关闭

    如果直接进入CLOSE状态,由于IP协议的不可靠性或者因为网络原因,主机2没有收到主机1最后回复的ACK,在超时后主机2会继续发送FIN,因为主机1已经没有了与之相对应的连接,最后主机2就会收到RST而不是ACK,主机2会将问题报告给上层处理。虽然这样不会造成数据的丢失,但是这不符合TCP的可靠性要求,所以需要等待,主机进入TIME_WAIT状态,当再次收到FIN的时候,确保主机2能够收到ACK。最后正常的关闭连接

  • 2.保证这个连接的重复数据在网络中消失

    如果直接进入了CLOSE状态,然后有向服务端发送新的连接请求。因为不能保证两次连接请求的端口是否一样。如果出现特殊情况,两次端口都一样,旧的连接数据还存在网络中,新的连接建立后,就连接的数据到达服务端,服务端会将其视为新连接传输的数据,这就导致新旧连接的数据混淆了。所以需要等待2MSL的时间,这样才能保证数据从网络中消失。

为什么连接需要三次握手而释放需要四次握手

建立连接的时候服务端收到建立连接的SYN请求后,将ACK和SYN放在一个报文里发送给客户端了。而释放的时候,当收到对方的FIN报文的时候,仅仅表示对方不在发送数据了,但是还可以接收数据,而己方可能还有数据发送,所以己方可以立即close连接或者发送一些数据给对方后再发送FIN报文给对方,表示可以释放连接,所以释放的时候ACK和FIN是分开发送的,所以需要四次挥手。

7.UDP协议

定义:用户数据协议

特点:面向无连接、不可靠、面向报文、没有拥塞控制

  • 面向无连接:和TCP相比,UDP是无连接的,将数据发送出去就不管了,不管是否到达是否丢失
  • 不可靠:数据发送出去就不管了,不管是否到达丢失
  • 面向报文:数据发送不像TCP面向字节流发送,UDP是将数据打包然后发送,不会像TCP那样拆分,UDP发送最大数据包是64K
  • 没有拥塞控制:当网络拥塞时,网络无法及时处理发送的数据,可能数据会丢失,TCP会不断重发,确保数据能够准确到达,所以TCP需要一个拥塞控制来控制数据发送。而UDP只是将数据发送出去就不管了,所以不需要拥塞控制。

8.HTTP协议

8.1 定义

超文本传输协议

8.2 特点

  • 无连接:在使用HTTP前不需要建立连接,服务端每次只处理客户端的一个请求,处理完请求并受到客户端的回应后就断开连接,这样节省传输时间
  • 无状态:HTTP的传输是无状态,即在数据传输过程中并不会保存任何历史信息和状态信息。当请求不需要前面的信息时应答速度会比较快,便于处理大量并发连接。
  • 传输可靠性高:HTTP传输需要建立TCP连接(TCP连接可靠性高),交换报文时需要事先建立TCP连接
  • 简单快速:每次请求时只需要发送请求方法和请求路径
  • 灵活:HTTP可以传输任何类型的数据
  • 兼容性好:支持B/S和C/S架构

8.3 URL

URL中文是统一资源定位符,用来表示某一处资源的地址

通过下面的URL来介绍URL的各个部分

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

  • 1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在”HTTP”后面的“//”为分隔符
  • 2.域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
  • 3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,- 如果省略端口部分,将采用默认端口
  • 4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
  • 5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  • 6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
  • 7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

8.4 URI与URL的区别

URI是统一资源标识符,用来唯一的标识一个资源

URI有三部分组成

  • 访问资源的命名机制
  • 存放资源的主机名
  • 资源的自身名称,着重强调资源,由路径表示

URL是一个具体的URL

URL由但部分组成

  • 协议
  • 访问资源的主机IP地址
  • 资源的具体路径

在Java中URI可以是相对的也可以是绝对的,只要符合URI语法即可,而URL是具体的,URL不但符合语法还包含了定位资源的信息,通过URL可以打开一个资源。

8.5HTTP请求Request

客户端发送请求到服务端的请求信息包含如下部分

请求行 请求头 空格 请求体

GET请求示例

GET /562f25980001b1b106000338.jpg HTTP/1.1
    Host    img.mukewang.com
    User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/51.0.2704.106 Safari/537.36
    Accept    image/webp,image/*,*/*;q=0.8
    Referer    http://www.imooc.com/
    Accept-Encoding    gzip, deflate, sdch
    Accept-Language    zh-CN,zh;q=0.8

POST请求示例

POST / HTTP1.1
    Host:www.wrox.com
    User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
    Content-Type:application/x-www-form-urlencoded
    Content-Length:40
    Connection: Keep-Alive

    name=Professional%20Ajax&publisher=Wiley

第一部分:请求行,第一行明了是post请求,以及http1.1版本。

第二部分:请求头部,第二行至第六行。

第三部分:空行,第七行的空行。

第四部分:请求数据,第八行。

8.6 HTTP请求响应Response

HTTP响应消息有四部分组成:状态行、消息报头、空行、响应正文

  • 第一部分:状态行:由HTTP协议版本,状态码,状态消息三部分组成
  • 第二部分:消息报头:用来说明客户端使用的一些附加信息
  • 第三部分:空行,消息报头后面的空行是必须的
  • 第四部分:响应正文

8.7 HTTP状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

  • 1xx:指示信息–表示请求已接收,继续处理
  • 2xx:成功–表示请求已被成功接收、理解、接受
  • 3xx:重定向–要完成请求必须进行更进一步的操作
  • 4xx:客户端错误–请求有语法错误或请求无法实现
  • 5xx:服务器端错误–服务器未能实现合法的请求

8.8 HTTP工作原理

HTTP协议采用请求/响应模型,客户端向服务端发送一个请求响应报文,报文内容包括:请求方法、URL、协议版本、请求头、请求数据。服务器收到请求后的响应结果包含:协议版本、状态码、状态信息、响应头(服务器信息)、响应正文。

一下是HTTP请求/响应步骤:

  • 1.客户端连接Web服务器

    客户端HTTP浏览器与Web服务器的端口建立TCP套接字连接

  • 2.发送HTTP请求

    通过TCP套接字连接,客户端向Web服务器发送请求报文,请求报文由请求行、请求头、空行、请求数据组成

  • 3.服务端接收HTTP请求并响应

    Web服务器解析请求并定位请求资源,服务器将请求资源副本写入到TCP套接字,由客户端读取,响应报文包括:响应行、响应头、空格、响应数据。

  • 4.释放TCP连接

    如果connection模式为close模式,则服务器主动关闭连接,客户端被动关闭连接。如果connection模式为keepalive,则该连接会包含一段时间,在这段时间内客户端和服务端可以持续发送和接收数据。

  • 5.客户端浏览器解析HTTP响应

    客户端浏览器首先解析状态行,查看表明是否成功的状态码,然后读取响应头,然后读取响应数据。

在浏览器地址栏键入URL,按下回车之后会经历以下流程:

  • 1、浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址;
  • 2、解析出IP地址后,根据该IP地址和默认端口80,和服务器建立TCP连接;
  • 3、浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器;
  • 4、服务器对浏览器请求作出响应,并把对应的html文本发送给浏览器;
  • 5、释放TCP连接;
  • 6、浏览器将该html文本并显示内容;  

8.9 GET和POST的区别

  • 1.GET提交的数据放在URL之后,用?来分隔URL和提交的数据,数据直接用&隔开,POST提交的数据放在请求的Body中
  • 2.GET的提交的数据有限制,虽然HTTP对GET提交的数据没有限制,但是因为浏览器的地址栏长度有限制,所以GET提交数据受地址栏长度的限制。因为POST提交的数据放在Body中,所以没有限制
  • 3.GET的请求方式需要通过Request.QueryString来获取数据,POST的请求方式需要通过Request.Form来获取数据
  • 4.GET的请求方式不安全,因为请求数据可以在浏览器地址栏中看到,因为POST的请求数据是放在POST中的,所以数据看不到。

QQ交流群

微信公众号:android在路上,欢迎关注

以上是关于Socket与HTTP解析的主要内容,如果未能解决你的问题,请参考以下文章

关于socket的疑问

Socket 与 WebSocket

socket连接方式

基于java的socket编程及API解析

Socket与Http区别、优缺点及应用场景

解析来自 TCP 流的 HTTP 响应