Java 面试题之网络通信

网络通信

HTTP

题1. http 是无状态通信,http 的请求方式有哪些,可以自己定义新的请求方式么。

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

  • GET 请求指定的页面信息,并返回实体主体。
  • HEAD 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头
  • POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
  • PUT 从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE 请求服务器删除指定的页面。
  • CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
  • OPTIONS 允许客户端查看服务器的性能。
  • TRACE 回显服务器收到的请求,主要用于测试或诊断。

注意:

  • 方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码 405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码 501(Not Implemented)。
  • HTTP 服务器至少应该实现 GET 和 HEAD/POST 方法,其他方法都是可选的,此外除上述方法,特定的 HTTP 服务器支持扩展自定义的方法。
  • 使用 GET 时,form 中的数据集(如 input 框的 value)将被编码到 URL 中,作为 URL 的一部分。而使用 POST 时,form 中的数据集则被编码到 http 协议的 header 中,构造成消息发送。在使用上,当且仅当请求是幂等(请求任意次都返回同样的结果)时使用 GET,而当请求会改变服务器数据或状态时使用 POST。当程序设计人员正确的使用 GET,POST 时,浏览器会给出更好的缓存配合,使响应速度更快。

SOCKET

题2. socket 通信,以及长连接,分包,连接异常断开的处理。

(1)socket 通信解析

socket 在哪一层?

socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“打开 open –> 读写 write/read –> 关闭 close”模式来操作。

  • TCP 服务器端依次调用 socket()、bind()、listen() 之后,就会监听指定的 socket 地址了。
  • TCP 客户端依次调用 socket()、connect() 之后就想TCP服务器发送了一个连接请求。TCP 服务器监听到这个请求之后,就会调用 accept() 函数取接收请求,这样连接就建立好了。之后就可以开始网络 I/O 操作了,即类同于普通文件的读写 I/O 操作。

先从服务器端说起。服务器端先初始化 Socket,然后与端口绑定(bind),对端口进行监听(listen),调用 accept 阻塞,等待客户端连接。在这时如果有个客户端初始化一个 Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

具体请看:

(2)长连接与短连接

  • 长连接:指在一个 TCP 连接上可以连续发送多个数据包,在 TCP 连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接;一般需要自己做在线维持。
  • 短连接:指通信双方有数据交互时,就建立一个 TCP 连接,数据发送完成后,则断开此TCP连接;一般银行都使用短连接。它的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。

比如 http 的,只是连接、请求、关闭,过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态。

长连接与短连接的操作过程:

  • 通常的短连接操作步骤是:连接→数据传输→关闭连接;
  • 长连接通常就是:连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接;

长连接就要求长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态,短连接在没有数据传输时直接关闭就行了。

什么时候用长连接,短连接?

  • 长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个 TCP 连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,下次次处理时直接发送数据包就 OK 了,不用建立 TCP 连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成 socket 错误,而且频繁的 socket 创建也是对资源的浪费。

(3)socket的半包,粘包与分包的问题

之所以出现粘包和半包现象,是因为 TCP 当中,只有流的概念,没有包的概念。

  • 半包指接受方没有接受到一个完整的包,只接受了部分,这种情况主要是由于 TCP 为提高传输效率,将一个包分配的足够大,导致接受方并不能一次接受完。(在长连接和短连接中都会出现)。
  • 粘包与分包指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。发送方引起的粘包是由 TCP 协议本身造成的,TCP 为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常 TCP 会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。分包是指在出现粘包的时候我们的接收方要进行分包处理。(在长连接中都会出现)

什么时候需要考虑半包的情况?

从备注中我们了解到 Socket 内部默认的收发缓冲区大小大概是 8K,但是我们在实际中往往需要考虑效率问题,重新配置了这个值,来达到系统的最佳状态。

一个实际中的例子:用 mina 作为服务器端,使用的缓存大小为 10k,这里使用的是短连接,所有不用考虑粘包的问题。

问题描述:在并发量比较大的情况下,就会出现一次接受并不能完整的获取所有的数据。

处理方式:

1、通过包头+包长+包体的协议形式,当服务器端获取到指定的包长时才说明获取完整。

2、指定包的结束标识,这样当我们获取到指定的标识时,说明包获取完整。

什么时候需要考虑粘包的情况?

  • 当时短连接的情况下,不用考虑粘包的情况
  • 如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储就 ok,也不用考虑粘包
  • 如果双方建立连接,需要在连接后一段时间内发送不同结构数据

如何处理粘包?

  • 接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开
    注:粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包

备注:
一个包没有固定长度,以太网限制在 46-1500 字节,1500就是以太网的MTU,超过这个量,TCP会为IP数据报设置偏移量进行分片传输,现在一般可允许应用层设置8k(NTFS系)的缓冲区,8k的数据由底层分片,而应用看来只是一次发送。windows 的缓冲区经验值是 4k,Socket 本身分为两种,流 (TCP) 和数据报 (UDP),你的问题针对这两种不同使用而结论不一样。甚至还和你是用阻塞、还是非阻塞 Socket 来编程有关。
1、通信长度,这个是你自己决定的,没有系统强迫你要发多大的包,实际应该根据需求和网络状况来决定。对于 TCP,这个长度可以大点,但要知道,Socket 内部默认的收发缓冲区大小大概是8K,你可以用 SetSockOpt 来改变。但对于 UDP,就不要太大,一般在 1024 至 10K。注意一点,你无论发多大的包,IP 层和链路层都会把你的包进行分片发送,一般局域网就是 1500 左右,广域网就只有几十字节。分片后的包将经过不同的路由到达接收方,对于 UDP 而言,要是其中一个分片丢失,那么接收方的 IP 层将把整个发送包丢弃,这就形成丢包。显然,要是一个 UDP 发包佷大,它被分片后,链路层丢失分片的几率就佷大,你这个 UDP 包,就佷容易丢失,但是太小又影响效率。最好可以配置这个值,以根据不同的环境来调整到最佳状态。
send() 函数返回了实际发送的长度,在网络不断的情况下,它绝不会返回(发送失败的)错误,最多就是返回0。对于 TCP 你可以字节写一个循环发送。当send函数返回 SOCKET_ERROR 时,才标志着有错误。但对于 UDP,你不要写循环发送,否则将给你的接收带来极大的麻烦。所以 UDP 需要用 SetSockOpt 来改变 Socket 内部 Buffer 的大小,以能容纳你的发包。明确一点,TCP 作为流,发包是不会整包到达的,而是源源不断的到,那接收方就必须组包。而UDP作为消息或数据报,它一定是整包到达接收方。
2、关于接收,一般的发包都有包边界,首要的就是你这个包的长度要让接收方知道,于是就有个包头信息,对于 TCP,接收方先收这个包头信息,然后再收包数据。一次收齐整个包也可以,可要对结果是否收齐进行验证。这也就完成了组包过程。UDP,那你只能整包接收了。要是你提供的接收 Buffer 过小,TCP 将返回实际接收的长度,余下的还可以收,而 UDP 不同的是,余下的数据被丢弃并返回 WSAEMSGSIZE 错误。注意 TCP,要是你提供的 Buffer 佷大,那么可能收到的就是多个发包,你必须分离它们,还有就是当 Buffer 太小,而一次收不完 Socket 内部的数据,那么 Socket 接收事件(OnReceive),可能不会再触发,使用事件方式进行接收时,密切注意这点。这些特性就是体现了流和数据包的区别。

(4)连接异常断开的处理

网络异常断开原因主要有那些呢?归纳起来主要有以下两种:

  • 1、客户端程序异常。对于这种情况,我们很好处理,因为客户端程序异常退出会在服务端引发 connectionreset 的 socket 异常(就是 winsock2 中的 10054 异常)。只要在服务端处理这个异常就可以了。
  • 2、网络链路异常。如:网线拔出、交换机掉电、客户端机器掉电。当出现这些情况的时候服务端不会出现任何异常。这样的话上面的代码就不能处理这种情况了。 对于这种情况在 MSDN 里面是这样处理的,原文如下:如果您需要确定连接的当前状态,请进行非阻止、零字节的 Send 调用。如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;否则,该套接字不再处于连接状态。但是,在试验中发现,这种处理方法在很多时候根本无效,尤其对发生在物理链路层上的问题,很多情况下无法检测出网络已经异常断开了。

下面探讨一下能够使用的判断与处理方式以及优缺点。

  • (1)定时发送简单约定帧

一般是服务器程序和客户端程序达成某种协议,客户端定时向服务器发送很小的数据包,即约定的简单帧,来告诉自己的状态,而服务器端程序则需要在每次收到用户的后更新用户超时的时间计数,当用户的时间计数超过指定时间,就可以认为这个用户已经系统异常终止,而终止之间的连接,并转告其他用户。客户端也可以通过接收服务器端返回的小数据包来判断服务器端的状态。

  • (2)Ping + Send/Receive

用 Ping 命令来判断网络本身状态,即确定物理链路层的状态。同时,用应用程序层的 Send 和 Receive 来进行程序/进程异常的判断。通过这两种方式的组合,一般能够正确得到网络的状态。当网络发生故障时,能够准确的定位其状态。

但是,当网络正常、应用程序正常时,对端的操作系统的设置可能会影响上述判断。即,当对端禁止向其发送 Ping 命令时,我们 Ping 的结果将始终为不通。考虑这种情况下,该方法存在一定的缺陷。

  • (3)KeepAlive-Timer

由于在应用层进行判断存在各种困难,那么是否可以考虑使用TCP底层的一些特性呢?通过思考,我想到可以利用 TCP 底层协议的 KeepAlive-Timer 进行网络状态的判断。但是需要改造。通过改造后,这将是一个比较可靠的判断方式。

如果在 2 个小时没有数据传送,TCP 协议会给对端发送一个 Keep-Alive 数据报,使用的序列号是曾经发出的最后一个报文的最后一个字节的序列号,对端如果收到这个数据,回送一个 TCP 的 ACK,确认这个字节已经收到,这样就知道此连接没有被断开。如果一段时间没有收到对方的响应,会进行重试,每隔 75 秒探测一次,重试 9 次后,没有收到回应的话,就会断开这个连接。

但 2 个小时对于我们的项目来说显然太长了。我们必须缩短这个时间。

我们要做的就是,在 TCP 认为的空闲2小时到达之前,模拟 keepAlive-Timer 的数据结构,使其按照我们的要求空闲时间、探测间隔来判断TCP的连接状态。 通过利用 Socket 类的 IOControl() 函数可以达到上述的目的。

题3. socket 通信模型的使用,AIO 和 NIO。

BIO | NIO | AIO 以 Java 的角度,理解,linux c 里也有 AIO 的概念(库),这些概念不知道什么原因被炒火起来,这里只从 Java 角度入手。

  • BIO,同步阻塞式IO,简单理解:一个连接一个线程
  • NIO,同步非阻塞IO,简单理解:一个请求一个线程
  • AIO,异步非阻塞IO,简单理解:一个有效请求一个线程

具体解析如下:

  • BIO(阻塞 IO),也就是传统的 IO,在进行数据读取时,在数据准备好之前,线程一直挂起,而数据从准备好,需经过硬盘,OS 内核(Kernel),JVM,这时一个漫长的过程,但是每一个 SOCKET 连接,都需要一个线程来监听,对于传输小数据的短连接问题还不大,如果是传输大数据的长连接,那就会有大量线程在系统中,非常浪费内存。
  • java1.4 版本出现 NIO(New IO),非阻塞型 IO,由 SocketChannel 来监听所有 I/O 事件,通常会创建一个 java.nio.channels.Selector 选择器用来获取 SelectionKey,然后根据该 Key 的事件类型处理,通信方式不再是传统的 Socket 而是 Channel,将连接和读或写的事件,在 SocketChannel 中注册,事件注册在 Kernel(系统内核)中,只有真正事件触发了,才会新建线程去处理返回值,NIO 是使用单线程或者只使用少量的多线程,每个连接共用一个线程。线程的利用率提高,他的场景通常是 I/O 密集,尤其是基于长连接的频繁交互。
  • Java1.7 出现 AIO,异步 IO 模型,在 NIO 的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有 BIO 一样的问题。 AIO中,I/O 的事情已经交给内核处理,线程只关注业务,无需等待 I/O返回值,AIO 相对 NIO 进一步提升了资源利用率,单这仅仅是相对进程本身而言,整个服务器而言还得看实际情况。这个模型 JAVA 提供两种机制来实现
    • 第一种是基于回调,实现接口 CompletionHandler 然后将这个实体传递给相应 API,会就在事件触发时自动回调。回调时启用其他线程来处理,可以用线程池。
    • 另一种是返回一个 Future,这个 Future 中有一个方法叫 isDone(),若该方法成立,那么数据就准备好了,或者通过 get() 等待数据完成,显然,isDone() 类似于 NIO 中的线程判定事件,get() 类似传统阻塞 I/O。它虽然是 AIO 模型但是并没有达到目的。
  • DirectBuffer:可以直接映射磁盘,跳过内核到 JVM 的内存拷贝,但是分配内存时,开销巨大,看情况使用,一般创建后尽量重复利用。
  • 在将数据读取到内存时,一定要注意阀值,分两种情况处理,小于阀值的数据直接处理,大于的,每次读取设定的阀值长度数据,分批处理。

具体请看:http://blog.csdn.net/zhang0558/article/details/53642063

NETTY

题4. socket 框架 netty 的使用,以及 NIO 的实现原理,为什么是异步非阻塞。

(1)socket 框架 netty 的使用

Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

Netty 是典型的 Reactor 模型结构,在实现上,Netty 中的 Boss 类充当 mainReactor, NioWorker 类充当 subReactor(默认 NioWorker 的个数是当前服务器的可用核数)。

在处理新来的请求时,NioWorker 读完已收到的数据到 ChannelBuffer 中,之后触发ChannelPipeline 中的 ChannelHandler 流。

Netty 是事件驱动的,可以通过 ChannelHandler 链来控制执行流向。因为 ChannelHandler 链的执行过程是在 subReactor 中同步的,所以如果业务处理 handler 耗时长,将严重影响可支持的并发数。

具体请看:

(2)NIO 的实现原理,为什么是异步非阻塞

下面是 Java NIO 的工作原理:

  1. 由一个专门的线程来处理所有的 IO 事件,并负责分发。
  2. 事件驱动机制:事件到的时候触发,而不是同步的去监视事件。
  3. 线程通讯:线程之间通过 wait,notify 等方式通讯。保证每次上下文切换都是有意义的。减少无谓的线程切换。

NIO基于 Reactor,当 socket 有流可读或可写入 socket 时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。 也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。

NIO 非堵塞技术实际是采取 Reacto r模式,或者说是 Observer 模式为我们监察 I/O 端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的 I/O 读写,不堵塞了。

具体请看:http://blog.csdn.net/zmx729618/article/details/51858230

题5. 同步和异步,阻塞和非阻塞。

“阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。

  • 同步与异步同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。典型的异步编程模型比如Node.js

举个通俗的例子:你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

  • 阻塞与非阻塞阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子,你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

具体请看:

OSI

题6. OSI 七层模型,包括 TCP,IP 的一些基本知识

(1)OSI 七层模型

OSI 是 Open System Interconnect 的缩写,意为开放式系统互联。

OSI七 层参考模型的各个层次的划分遵循下列原则:

  1. 同一层中的各网络节点都有相同的层次结构,具有同样的功能。
  2. 同一节点内相邻层之间通过接口(可以是逻辑接口)进行通信。
  3. 七层结构中的每一层使用下一层提供的服务,并且向其上层提供服务。
  4. 不同节点的同等层按照协议实现对等层之间的通信。

1)第一层:物理层(PhysicalLayer)

规定通信设备的机械的、电气的、功能的和过程的特性,用以建立、维护和拆除物理链路连接。具体地讲,机械 特性规定了网络连接时所需接插件的规格尺寸、引脚数量和排列情况等;电气特性规定了在物理连接上传输bit流时线路上信号电平的大小、阻抗匹配、传输速率 距离限制等;功能特性是指对各个信号先分配确切的信号含义,即定义了DTE和DCE之间各个线路的功能;规程特性定义了利用信号线进行bit流传输的一组 操作规程,是指在物理连接的建立、维护、交换信息是,DTE和DCE双放在各电路上的动作系列。在这一层,数据的单位称为比特(bit)。属于物理层定义的典型规范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。

2)第二层:数据链路层(DataLinkLayer):

在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路,通过差错控制提供数据帧(Frame)在信道上无差错的传输,并进行各电路上的动作系列。数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)。数据链路层协议的代表包括:SDLC、HDLC、PPP、STP、帧中继等。

3)第三层是网络层

在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息- -源站点和目的站点地址的网络地址。如果你在谈论一个 IP 地址,那么你是在处理第 3 层的问题,这是“数据包”问题,而不是第2层的“帧”。IP 是第 3 层问题的一部分,此外还有一些路由协议和地 址解析协议(ARP)。有关路由的一切事情都在这第3层处理。地址解析和路由是 3 层的重要目的。网络层还可以实现拥塞控制、网际互连等功能。在这一层,数据的单位称为数据包(packet)。网络层协议的代表包括:IP、IPX、RIP、OSPF 等。

4)第四层是处理信息的传输层

第 4 层的数据单元也称作数据包(packets)。但是,当你谈论 TCP 等具体的协议时又有特殊的叫法,TCP 的数据单元称为段 (segments)而UDP协议的数据单元称为“数据报(datagrams)”。这个层负责获取全部信息,因此,它必须跟踪数据单元碎片、乱序到达的 数据包和其它在传输过程中可能发生的危险。第4层为上层提供端到端(最终用户到最终用户)的透明的、可靠的数据传输服务。所为透明的传输是指在通信过程中 传输层对上层屏蔽了通信传输系统的具体细节。传输层协议的代表包括:TCP、UDP、SPX 等。

5)第五层是会话层

这一层也可以称为会晤层或对话层,在会话层及以上的高层次中,数据传送的单位不再另外命名,而是统称为报文。会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验证用户登录便是由会话层完成的。

6)第六层是表示层

这一层主要解决拥护信息的语法表示问题。它将欲交换的数据从适合于某一用户的抽象语法,转换为适合于 OSI 系统内部使用的传送语法。即提供格式化的表示和转换数据服务。数据的压缩和解压缩, 加密和解密等工作都由表示层负责。

7)第七层应用层

应用层为操作系统或网络应用程序提供访问网络服务的接口。应用层协议的代表包括:Telnet、FTP、HTTP、SNMP 等。

具体请看:http://www.ha97.com/3215.html

(2)TCP,IP 的一些基本知识

具体请看:http://www.cnblogs.com/glacierh/p/4854009.html

题7. http 中,get post 的区别

两者区别总结成下表:

操作方式数据位置明文密文数据安全长度限制应用场景
GETHTTP包头明文不安全长度较小查询数据
POSTHTTP正文可明可密安全支持较大数据传输修改数据

具体请看:http://www.cnblogs.com/wangli-66/p/5453507.html

题8. 说说 http,tcp,udp 之间关系和区别。

  • TCP/IP 代表传输控制协议/网际协议,指的是一系列协议。TCP/IP 是个协议组,可分为三个层次:网络层、传输层和应用层。在网络层有 IP 协议、ICMP 协议、ARP 协议、RARP 协议和 BOOTP 协议。在传输层中有 TCP 协议与 UDP 协议。在应用层有 FTP、HTTP、TELNET、SMTP、DNS 等协议。
  • TCP 和 UDP 使用 IP 协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP 和 UDP 是高速公路上的“卡车”,它们携带的货物就是像 HTTP,文件传输协议 FTP 这样的协议等。
  • TCP 和 UDP 是 FTP,HTTP 和 SMTP 之类使用的传输层协议。虽然 TCP 和 UDP 都是用来传输其他协议的,它们却有一个显著的不同:TCP 提供有保证的数据传输,而 UDP 不提供。这意味着 TCP 有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而 UDP 不提供任何这样的保证。
  • HTTP (超文本传输协议)协议是建立在请求/响应模型上的。它是利用 TCP 在两台电脑(通常是Web 服务器和客户端)之间传输信息的协议。客户端使用Web浏览器发起 HTTP 请求给 Web 服务器,Web 服务器发送被请求的信息给客户端。

题9. 说说浏览器访问www.taobao.com,经历了怎样的过程。

根据域名查询IP地址的顺序如下:

浏览器DNS >>> 操作系统DNS缓存 >>> 本地(ISP)域名服务器缓存 >>> 根域名服务器。

(1)首先是查找浏览器缓存,浏览器会保存一段时间你之前访问过的一些网址的DNS信息,不同浏览器保存的时常不等。如果没有找到对应的记录,这个时候浏览器会尝试调用系统缓存来继续查找这个网址的对应DNS信息。如果还是没找到对应的IP,那么接着会发送一个请求到路由器上,然后路由器在自己的路由器缓存上查找记录,路由器一般也存有DNS信息。如果还是没有,这个请求就会被发送到ISP(注:Internet Service Provider,互联网服务提供商,就是那些拉网线到你家里的运营商,中国电信中国移动什么的),ISP也会有相应的ISP DNS服务器,一听中国电信就知道这个DNS服务器的规模肯定不会小,所以基本上都能在这里找得到。如果还是没有的话, 你的ISP的DNS服务器会将请求发向根域名服务器进行搜索。根域名服务器就是面向全球的顶级DNS服务器,共有13台逻辑上的服务器,从A到M命名,真正的实体服务器则有几百台,分布于全球各大洲。所以这些服务器有真正完整的DNS数据库。如果到了这里还是找不到域名的对应信息,那只能说明一个问题:这个域名本来就不存在,它没有在网上正式注册过。或者卖域名的把它回收掉了(通常是因为欠费)。多说一句,例如"mp3.baidu.com",域名先是解析出这是个.com的域名,然后跑到管理.com域名的服务器上进行进一步查询,然后是.baidu,最后是mp3,所以域名结构为:三级域名.二级域名.一级域名。

(2)浏览器主机根据IP地址与服务器建立TCP连接。

(3)浏览器将访问请求封装为一个HTTP请求报文,通过TCP协议发送给服务器。

(4)服务器收到请求并响应,生成一个HTTP响应报文,通过TCP协议发送给浏览器主机。

(5)浏览器得到响应报文之后,对响应报文进行解析。

(6)浏览器异步请求其他资源。在分析HTML时,若发现网页引用了其他资源,例如:css、图片等,浏览器则发起HTTP请求,得到响应资源。

具体请看:

HTTPS

题10. HTTP 协议、 HTTPS协议,SSL协议及完整交互过程;

(1)HTTP 协议

HTTP 是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。

HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP 协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

(2)HTTPS 协议

HTTPS 的工作原理:我们都知道 HTTPS 能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用 HTTPS 协议。

  • 1)客户端发起 HTTPS 请求

这个没什么好说的,就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口。

  • 2)服务端的配置

采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。
这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

  • 3)传送证书

这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

  • 4)客户端解析证书

这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。
如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

  • 5)传送加密信息

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

  • 6)服务段解密信息

服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

  • 7)传输加密后的信息

这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。

  • 8)客户端解密信息

客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。

HTTP 与 HTTPS 有什么区别?

HTTP 协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了 SSL(Secure Sockets Layer)协议用于对 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。

简单来说,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 http 协议安全。

HTTPS 和 HTTP 的区别主要如下:

  • https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。
  • http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
  • http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  • http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。

(3)SSL 协议

SSL 协议位于 TCP/IP 协议与各种应用层协议之间,是一种国际标准的加密及身份认证通信协议,为 TCP 提供一个可靠的端到端的安全服务,为两个通讯个体之间提供保密性和完整性(身份鉴别)。SSL 协议可分为两层:SSL 记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL 握手协议(SSL Handshake Protocol):它建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

SSL的位置:

SSL协议工作的基本流程:

  • 接通阶段:客户机通过网络向服务器打招呼,服务器回应
  • 密码交换阶段:客户机与服务器之间交换双方认可的密码,一般选用RSA密码算法
  • 会谈密码阶段:客户机器与服务器间产生彼此交谈的会谈密码
  • 检验阶段:客户机检验服务器取得的密码
  • 客户认证阶段:服务器验证客户机的可信度
  • 结束阶段:客户机与服务器之间相互交换结束的信息

详细描述 (终于搞清流程了)

SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术。SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证,其主要过程如下:

1. 客户端的浏览器向服务器传送客户端SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息。

2. 服务器向客户端传送SSL 协议的版本号,加密算法的种类,随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。

3. 客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。

4. 用户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器。 (服务端验证成功)

5. 如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器。

6. 如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的CA 是否可靠,发行CA 的公钥能否正确解开客户证书的发行CA 的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。

7. 服务器和客户端用相同的主密码即“通话密码”,一个对称密钥用于SSL 协议的安全数据通讯的加解密通讯。同时在SSL 通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。

8. 客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤7中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。

9. 服务器向客户端发出信息,指明后面的数据通讯将使用的步骤7中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。

10. SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。

具体请看:

题11. tcp 的拥塞,快回传,ip的报文丢弃

(1)tcp 的流量控制、拥塞、快回传

所谓的流量控制就是让发送方的发送速率不要太快,让接收方来得及接受。利用滑动窗口机制可以很方便的在 TCP 连接上实现对发送方的流量控制。TCP 的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值。

  • 拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
  • 流量控制:指点对点通信量的控制,是端到端正的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

拥塞控制和流量控制的差别:

  • 所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能承受现有的网络负荷。
  • 流量控制往往指的是点对点通信量的控制,是个端到端的问题。流量控制所要做的就是控制发送端发送数据的速率,以便使接收端来得及接受。

具体请看:

(2)IP 的报文丢弃

IP 报文丢弃是 IP 协议服务尽最大努力投递服务的特点。当报文发送到目的地后,系统会有一系列的检测手段对收到的报文进行检测,要是有一个或者多个片丢失了,那么系统会会向报文的源目标地址发送一个请求,源目标地址收到请求了,会重新发送报文到目的地址。

IP 协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组。

IPV6 网络只在源和目的地分片和重组。如果丢失会重传。IpV4 网络是在每个节点间分片和重组。IPV4 的包头里有一个CRC效验就会检查报文是否完整。

对于不同的传输层协议,在 IP 层上,需不需要进行分片是不同的:

  • 对于 TCP 来说,它是尽量避免分片的。因为当在 IP 层进行了分片后,如果其中的某片数据丢失,则需对整个数据报进行重传。因为 IP 层本身没有超时重传机制,当来自 TCP 报文段的某一片丢失后,TCP 在超时后重发整个 TCP 报文段,该报文段对应于一份 IP 数据报,没有办法只重传数据报中的一个数据报片。而且如果对数据报分片的是中间路由器,而不是起始端系统,那么起始端系统就无法知道数据报是如何被分片的,因此基于这种原因,TCP 是经常要避免分片的。

那么 TCP 层是如何避免 IP 层的分片呢?首先,TCP 在建立连接时会进行3次握手,而在这3次握手中,客户端和服务端通常会协商一个值,那就是 MSS(最长报文大小),用来表示本段所能接收的最大长度的报文段。MSS=MTU-TCP 首部大小-IP 首部大小,MTU 值通过查询链路层得知。
当两端确认好 MSS 后进行通信,TCP 层往 IP 层传输数据时,如果 TCP 层缓冲区的大小大于MSS,那么 TCP 层都会将其中的数据分组进行传输,这样就避免了在 IP 层进行分片。

  • 对于 UDP 而言,由于 UDP 是不需要保证可靠性的,没有超时和重传机制,这使得UDP很容易导致IP分片。

那么数据报被分片后是怎样的呢,又是以何种算法进行分片呢?首先我们回忆IP首部:

对于每份 IP 数据报来说,其 16 位标识字段都包含一个唯一值。在数据报被分片时,这个值同时被复制到每个片中。

在 IP 首部中,我们看到有一个占了 3 位的标志字段,其中第1位作为保留字段;第 2 位分段用来表示一个数据报是否允许在 IP 层被分片;而第 3 位更多分片字段,则是当数据报被分片时,让接收端知道在什么时候完成所有的分片组装,除了最后一片外,其他每个组成数据报的片都要把该比特置 1。
而如果将其中的分段标志比特位置 1,表示不允许 IP 层对数据报进行分片。例如当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特,路由器会丢弃数据报并发送一个 ICMP 差错报文(“需要进行分片但设置了不分片比特”)。

IP 首部中 13 位的偏移量字段表示 IP 分片在整个数据流中的位置,第一个数据报分片的偏移量置为 0,而后续的分片偏移量则是根据网络的 MTU 大小设置,且必须为8的整数倍。

需要注意的是,任何传输层的首部只出现在第一片数据中,后续报文均不带传输层信息。
这是 IP 分片的第一个数据分片,可以看出其 IP 的上层协议为 ICMP 协议,而在后续的分片报文中却无法看到上层协议的具体信息。

接收方在收到经过 IP 层分片的数据报文后,首先根据分片标志中的更多分段位判断是否是最后一个分片报文,如果是,则根据分片偏移量计算各个分片报文在原始数据报中的位置,进行重组。如果不是最后一个分片,则需等待所有分片到达后再完成重组。

具体请看:http://www.cnblogs.com/therock/articles/3294077.html

题12. https 处理的一个过程,对称加密和非对称加密

(1)对称加密

所谓对称加密,就是它们在编码时使用的密钥 e 和解码时一样 d(e=d),我们就将其统称为密钥 k。

对称加解密的过程如下:

发送端和接收端首先要共享相同的密钥k(即通信前双方都需要知道对应的密钥)才能进行通信。发送端用共享密钥 k 对明文 p 进行加密,得到密文 c,并将得到的密文发送给接收端,接收端收到密文后,并用其相同的共享密钥 k 对密文进行解密,得出明文 p。

一般加密和解密的算法是公开的,需要保持隐秘的是密钥k,流行的对称加密算法有:DES,Triple-DES,RC2 和 RC4

(2)非对称加密

所谓非对称加密技术是指加密的密钥 e 和解密的密钥 d 是不同的(e!=d),并且加密的密钥e是公开的,叫做公钥,而解密的密钥d是保密的,叫私钥。

非对称加解密的过程如下:

加密一方找到接收方的公钥 e (如何找到呢?大部分的公钥查找工作实际上都是通过数字证书来实现的),然后用公钥 e 对明文 p 进行加密后得到密文 c,并将得到的密文发送给接收方,接收方收到密文后,用自己保留的私钥 d 进行解密,得到明文 p,需要注意的是:用公钥加密的密文,只有拥有私钥的一方才能解密,这样就可以解决加密的各方可以统一使用一个公钥即可。

常用的非对称加密算法有:RSA

具体请看:http://blog.csdn.net/qq_16681169/article/details/50933958

题13. head各个特点和区别

(1)Accept:告诉WEB服务器自己接受什么介质类型。

  • / 表示任何类型,
  • type/* 表示该类型下的所有子类型,
  • type/sub-type。

(2)Accept-Charset: 浏览器申明自己接收的字符集

  • Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
  • Accept-Language::浏览器申明自己接收的语言
    语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。

(3)Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。

  • bytes:表示接受
  • none:表示不接受。

(4)Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)

  • max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
  • max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)
  • min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象)
    响应:public(可以用 Cached 内容回应任何用户)
  • private(只能用缓存内容回应先前请求该内容的那个用户)
  • no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
  • max-age:(本响应包含的对象的过期时间)
  • ALL: no-store(不允许缓存)

具体请看:http://blog.csdn.net/tuxiangqi/article/details/8158258

文章目录
  1. 1. 网络通信
    1. 1.1. HTTP
    2. 1.2. SOCKET
    3. 1.3. NETTY
    4. 1.4. OSI
    5. 1.5. HTTPS
|