TCP/IP与HTTP相关总结

来源:互联网 发布:mac安装flash失败 编辑:程序博客网 时间:2024/05/19 02:28

网络其实大体分为两块,一个TCP协议,一个HTTP协议.

1.TCP与UDP区别

  • 建立连接与否

  • TCP面向数据流、UDP数据报。

  • TCP提供可靠,有序,不重复的数据传输;UDP只是将数据简单封装,交给IP层数据报传输,不提供超时重发等机制。

  • 如果数据包没有传输到对端,TCP套接口则返回一个错误状态。

  • TCP支持全双工通信,UDP支持一对一、一对多、多对一、多对多通信、

  • TCP的四种可靠机制

    • 确认(包含三次握手和四次断开)

    • 超时重传机制

    • 排序,以字节流方式传输,每一个比特都有自己的序号,丢弃重复数据

    • 滑动窗口实现流量控制。慢开始、拥塞避免、快重传、快恢复和快重传。

(流量控制是点对点的,其要实现的是对端能够接受数据;拥塞控制是全局性的,其旨在保证网络中的路由器和链路不至于过载)

TCP由于在通信之前需要建立连接,故而通信开销较大,是导致比UDP传输数据较慢。功能的简单,决定着UDP的报头大小要比TCP报头要小的多。

UDP不要求保持连接,通常应用于短应用和控制消息。

2.TCP三次握手与四次握手,状态名和含义,TIMEWAIT的作用

  • 上图中的MSS是最大报文长度大小(Maximum segment size)

  • TIME_WAIT状态
    每一个端点停留在此部分的时间为最大分节生命期(MSL)的两倍,有时候称之为2MSL。
    其意义有二,一是可靠地实现TCP全双工连接的终止、二是允许老的重复分组在网络中消失。

    • 可靠地实现TCP全双工连接的终止
      如果服务端发出一个FIN,客户端接收,回复ACK的包丢失,这时候如果没有TIME_WAIT状态,连接就结束,对于全双工服务器一端,其并没有正常结束,而是响应一个RST错误。留有这个状态,保证了服务器在发现超时重发最后一个FIN后,客户端仍能够重新回复一个ACK.**在此过程中,客户端向服务器发送ACK需要一个MSL,服务器未收到ACK发送一个FIN,此时需要一个MSL,故整个过程必须要2MSL.
    • 允许老的重复分组在网络中消失
      原来过期的连接请求可以在网络中消失。可能出现一种情况,即原来A端和B端的连接结束,在一定短时间内,原来一样的的连接重新建立,而上一个重复的包如果再到达对端,那么对端有可能接收此包,而导致接收错误。由于TIME_WAIT状态持续2MSL,足以使重复的分组最大生存MSL时间即被丢弃。
  • 为什么建立连接是三次握手,而不是两次握手
    此是为了防止客户端过期的连接请求消息,再次建立连接。比如有一个包在网络阻塞,但是并没有被丢弃,然后客户端重传,完成三次握手。再次之后,原来阻塞的包到达服务器,服务器回复一个SYN和ACK,如果仅仅是两次握手,此时,连接已建立。但是如果是三次握手,此时客户端并不回复此SYN+ACK包,故这种过期的连接就无法建立。
  • 为什么建立连接需要三次握手而断开连接需要四次握手
    在建立连接时,服务器对客户端SYN的ACK以及自身的ACK,可以放在一个分组包里发送给客户端,因为此时只是做同步。但是对于结束时,TCP在做全双工工作,客户端向服务器发送一个FIN代表的是客户端发送数据的完成,但是服务器的数据发送数据并不一定完成,所以再接收到客户端发送FIN后,服务器将发送缓冲区的数据发送完之后,也发给客户端一个FIN。另一方面,客户端发送给服务器的EOF会在服务器的接收缓冲区内排队,需要接收缓冲区的数据完成,才能实现对EOF的响应。只有把TCP报头控制字段中的PUSH置一,才能立即处理EOF,但此时同时需要保证发送缓冲区数据的完成。

3. TCP拥塞控制

  • 慢启动:由1指数增加

  • 拥塞避免:到达拥塞门限后,线性增加。如果出现拥塞,则将拥塞门限降为原来的一半,同时将拥塞窗口置1,再次指数增加。

  • 快重传:要求接收方收到一个失序的包时,立即回复重传,而不是在自己发送数据时,捎带重传数据。当连续三次收到重传请求时,不必等到重传定时到期,就去重传。

  • 快恢复:当发送方连续收到三个重复确认之后,把拥塞门限减半,但是此时不执行慢开始,而是拥塞避免算法。

4. Http的报文结构。

请求行, 请求头, 请求内容

  • 请求方法:
    • GET
      请求获取Request-URI所标识的资源(需要返回数据)
    • POST
      在Request-URI所标识的资源后附加新的数据(新加数据)
    • HEAD
    • 请求获取由Request-URI所标识的资源的响应消息报头(和GET类似,不需要返回数据,故只有报头)
    • PUT
      请求服务器存储一个资源,并用Request-URI作为其标识(修改数据)
    • DELETE
      请求服务器删除Request-URI所标识的资源(删除数据) TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
    • CONNECT 保留将来使用 OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
  • 请求头(未记熟的)

    • Accept-Charset
      请求报头域用于指定客户端接受的字符集。eg:Accept-Charset:iso-8859-1,gb2312.
    • connection:Keep-alive.
      在非keep-alive模式下,C/S两端的每一次请求都是请求应答模式,每一次请求也都伴随着一次TCP的连接建立。当一次请求应答结束后,就断开连接。而在keep-alive模式下实现了连接的复用,即如有下次的请求,服务端之间的连接持续有效,避免了重复建立连接。但是这个连接是有一定的持续时间。比如一个网页的html中有图像文件,但是在html中,只是一个src标签对应的url。如果没有保持连接,就导致请求到html了,又重新建立连接去请求图像的URL。在含有大量JS CSS的网页中也会出现这种情况。
      http 1.0中默认是关闭的,需要在http头加入”Connection: Keep-Alive”,才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入”Connection: close “,才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况。

    • keep-alive的优势:

      • 较少的CPU和内存的使用(由于同时打开的连接的减少了)

      • 允许请求和应答的HTTP管线化

      • 降低网络阻塞 (TCP连接减少了)

      • 减少了后续请求的延迟(无需再进行握手)

      • 报告错误无需关闭TCP连接

    • referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。

    • 在keep-alive模式下是如何判断一次数据传输完毕,可以通过content-length字段,因为它标识了内容的长度,但是对于一些动态页面,是边发边产生数据,这就没法计算此字段值,此时就需要使用Chunked协议

    • ransfer-Encoding:chunked 服务器就需要使用”Transfer-Encoding: chunked”这样的方式来代替Content-Length。chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0 的chunk标示结束。

5.Http的状态码含义

1xx:指示信息–表示请求已接收,继续处理。

2xx:成功–表示请求已被成功接收、理解、接受。

3xx:重定向–要完成请求必须进行更进一步的操作。

4xx:客户端错误–请求有语法错误或请求无法实现。

5xx:服务器端错误–服务器未能实现合法的请求。

常见状态代码、状态描述的说明如下。

200 OK:客户端请求成功。

400 Bad Request:客户端请求有语法错误,不能被服务器所理解。

401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。

403 Forbidden:服务器收到请求,但是拒绝提供服务。

404 Not Found:请求资源不存在,举个例子:输入了错误的URL。

500 Internal Server Error:服务器发生不可预期的错误。

503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。

6. Http1.1和Http1.0的区别

  • 连接复用,即上诉所说的connection字段

  • 增加了更多的请求包和响应包

  • 增加了host请求头。由于HTTP 1.0不支持Host请求头字段,WEB浏览器无法使用主机头名来明确表示要访问服务器上的哪个WEB站点,这样就无法使用WEB服务器在同一个IP地址和端口号上配置多个虚拟WEB站点。在HTTP 1.1中增加Host请求头字段后,WEB浏览器可以使用主机头名来明确表示要访问服务器上的哪个WEB站点,这才实现了在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点。

  • HTTP 1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。

7.http怎么处理长连接

HTTP的短链接就是在connection为false的情况下,即连接不复用。当connection为keep-alive时,即是长连接。

http的短连接和长连接即为TCP的短连接和长连接。

TCP短连接即为一次读写之后,断开连接。其优点是管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。

长连接是在读写之后,并不断开连接。下一次读写还用这个连接。与此功能想配合的即为TCP的保活功能,它为服务器而设计,这样是服务器想知道客户端状态,判断其是否奔溃。服务器在2小时内未收到客户端的任何请求,就会发一个探测报文。服务器就根据根据客户端的响应/未响应做一定的处理。

8.Cookie与Session的作用于原理

首先理解http的无状态。

HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

由于HTTP协议是无状态的,即客户端和服务器端,都没有必要记录对方的动作。但是在有些情况下,保持对方的状态,于是便出现了cookie和session.

cookie是位于客户端保持状态的方法。通过扩展http协议实现,在服务器通过在响应头部添加特殊的字段(set-cookies),使浏览器生成相应的cookie,cookie有作用范围和生存时间,如果请求的资源在其作用范围内,且cookie有效,其就将cookie发给服务器。

cookie有保存在内存的,也有保存在硬盘里的。如果未设置生存时间,则其保存在内存中,关闭浏览器,cookie也就消失,这种叫做会话cookie。如果设置了生存时间,则其保存在硬盘上,关闭浏览器下次打开后,还可以使用。

对于保存在硬盘上的cookie,可以实现浏览器之间的共享。对于保存在内存中的cookie,但是不同的浏览器表现不同。对于IE来说,使用ctrl+n创建的页面,能够实现共享,其他放方式均不能。对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie

session是一种在服务端保持状态的方法,当服务器要为某个请求创建session时,其首先检查客户端请求报头里是否有session-id,如果有的话,则说明此前已经创建过,服务器就按照sessionid 把其检测出来。如果没有session-id,则服务器创建一个session,并分配一个与其关联的session-id,session-id将在响应头中,交给客户端,让其保存。而session-id的可以以cookie的方式在客户端保存起来。

16. select, poll, epoll

参考1
参考2
参考3
参考4

select、poll、epoll都是IO多路复用的机制,一个进程可以监视多个描述符,一旦某个描述符就绪,则通知程序做相应的读写操作。他们本质上都是同步I/O.

  • select

select函数监视文件描述符有三类,分别为writefds、readfds、和exceptfds。调用select后进程阻塞,直到有描述符就绪的时候。select返回后,可以遍历fdset来查看就绪的描述符。

  • select的好处是几乎所有平台都支持。

  • select的缺点有三。

    1. 默认支持的描述符个数太少,为1024/2048,虽然可以修改,但需要重新需要编译内核。即使增加了支持的描述符,但同样会使内核遍历fd的开销线性增加。

    2. 每一次调用select,都会出现一次奖所有描述符由用户态复制到内核态的操作。同时,内核fd的状态也需要使用内存拷贝的方式,使其状态传递到用户层

    3. 对于每次从用户态传过来的fd,内核都需要遍历一遍,这同样会带来很大的开销。

  • poll

poll的机制和select差不多,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。

poll解决了连接数问题,因为poll的描述符是由链表来存储的,而不是数组。

  • epoll

epoll解决了select的所有问题,所以效率很高。

  1. 文件描述符个数不受限制。内部实现为红黑树数。

  2. 相对于select和poll 出现的fd在内核态与用户态之间的拷贝,epoll则使用了mmap共享内存的策略。

  3. epoll将所有fd加入到等待序列中,并且为其分配一个callback回调函数,当一个fd就绪,其就会在就绪序列中激活,并且调用callback,callback会将其加入到一个就绪链表,并唤醒在睡眠状态的epoll_wait。epoll_wait()检测此就绪链表是否为空即可。虽然和select一样,需要由睡眠到激活态,但是select的睡眠和激活是主动的,多次转换。而epoll的一次激活是在有就绪fd的情况下才被激活,避免了不必要的激活,同时epoll_wait()也只需要检测一下就绪链表是否为空即可,而不像select进行遍历。

epoll的两种工作模式

epoll有LT(水平触发)和ET(边缘触发)

其区别为在LT情况下,只要某个socket处于readable/writable状态,epoll_wait()就会返回该socket,但是对于边缘触发(edge_trigger),只要在状态变换,即由unreadable/unwritable到readable/writable状态变换时,才能返回socket。

select和poll都属于水平触发,即只要可读可写,就一直读取数据。对于epoll的边缘触发模式,就要可能出现问题。即当有一个边缘触发来之后,事件引发epoll_wait()返回socket并做相应的读取,但是当数据在第一次读取并未读取完时,并没有unreadable/unwritable到readable/writable状态的转换,来再次触发读数据,此时可能就放弃对数据的读取。所以这种情况下,读就一直读,工作在非阻塞情况下,直到返回EAGAIN.

1 0
原创粉丝点击