奇迹般的腾讯笔试通过了,昨天下午经过了一面…发现之前着眼于Android与Java的知识而没有对计算机网络系统的复习…导致了这次面试的滑铁卢…所以想进这样的一线大厂做一名合格的程序员还是要全面发展…不能顾此失彼

Http协议


  • 默认端口:80

Http协议的主要特点


  1. 支持客户/服务器模式
  2. 简单快速:客户向服务端请求服务时,只需传送请求方式和路径。
  3. 灵活:允许传输任意类型的数据对象。由Content-Type加以标记。
  4. 无连接:每次响应一个请求,响应完成以后就断开连接。
  5. 无状态:服务器不保存浏览器的任何信息。每次提交的请求之间没有关联。

非持续性和持续性


  • HTTP1.0默认非持续性;HTTP1.1默认持续性

持续性

浏览器和服务器建立TCP连接后,可以请求多个对象

非持续性

浏览器和服务器建立TCP连接后,只能请求一个对象

非流水线和流水线


类似于组成里面的流水操作

  • 流水线:不必等到收到服务器的回应就发送下一个报文。
  • 非流水线:发出一个报文,等到响应,再发下一个报文。类似TCP。

POST和GET的区别

Post一般用于更新或者添加资源信息 Get一般用于查询操作,而且应该是安全和幂等的
Post更加安全 Get会把请求的信息放到URL的后面
Post传输量一般无大小限制 Get不能大于2KB
Post执行效率低 Get执行效率略高

为什么POST效率低,Get效率高


  • Get将参数拼成URL,放到header消息头里传递
  • Post直接以键值对的形式放到消息体中传递。
  • 但两者的效率差距很小很小

Https


  • 端口号是443
  • 是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议。

Socket


使用TCP


客户端

1
2
3
4
5
6
7
Socket socket = new Socket("ip", 端口);
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
OutputStream os = socket.getOutputStream();
DataInputStream dos = new DataOutputStream(os);

服务器端

1
2
3
ServerSocket serverSocket = new ServerSocket(端口);
Socket socket = serverSocket.accept();
//获取流的方式与客户端一样

读取输入流

1
2
3
4
5
6
7
8
9
byte[] buffer = new byte[1024];
do{
int count = is.read(buffer);
if(count <= 0){ break; }
else{
// 对buffer保存或者做些其他操作
}
}
while(true);

使用UDP

客户端和服务器端一样的

1
2
3
4
5
6
7
8
9
DatagramSocket socket = new DatagramSocket(端口);
InetAddress serverAddress = InetAddress.getbyName("ip");
//发送
DatagramPackage packet = new DatagramPacket(buffer, length, host, port);
socket.send(packet);
//接收
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, 1024);
Socket.receive(packet);

TCP与UDP


面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会是IP太小。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。
面向字节流的话,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。

TCP协议



  • Transmission Control Protocol,传输控制协议
  • 面向连接的协议
  • 需要三次握手建立连接
  • 需要四次挥手断开连接
  • TCP报头最小长度:20字节

三次握手的过程:



  1. 客户端发送:SYN = 1, SEQ = X, 端口号
  2. 服务器回复:SYN = 1, ack = X + 1, SEQ = Y,ACK = 1
  3. 客户端发送:ack = Y + 1, SEQ = X + 1,ACK = 1
  • SYN – 建立连接位
  • ACK – 响应位
  • SEQ – 顺序号码
  • ack – 确认号

    确认应答信号ACK = 收到的SEQ + 1。
    连接建立中,同步信号SYN始终为1。连接建立后,同步信号SYN=0。

  • 第一次握手:主机A发送位码为SYN = 1,随机产生SEQ = 1234567的数据包到服务器,主机B由SYN = 1知道,A要建立联机

  • 第二次握手:主机B收到请求后要确认联机信息,向A发送ACK = (主机A的SEQ+1),SYN = 1,ack = 1,随机产生SEQ = 3452671的包;
  • 第三次握手:主机A收到后检查ack是否正确,即第一次发送的(SEQ+1),以及位码ACK是否为1,若正确,主机A会再发送ack = (主机B的SEQ+1),ACK = 1,主机B收到后确认SEQ值与ACK = 1则连接建立成功。

四次挥手过程



  1. A向B提出停止连接请求,FIN = 1
  2. B收到,ACK = 1
  3. B向A提出停止连接请求,FIN = 1
  4. A收到,ACK = 1
  • FIN – 关闭连接
  • SYN – 建立连接位
  • ACK – 响应位
  • SEQ – 顺序号码
  • ack – 确认号
    优点:

  • 可靠,稳定
    1、传递数据前,会有三次握手建立连接
    2、传递数据时,有确认、窗口、重传、拥塞控制
    3、传递数据后,会断开连接节省系统资源
    

缺点:


  • 传输慢,效率低,占用系统资源高
    1、传递数据前,建立连接需要耗时
    2、传递数据时,确认、重传、拥塞等会消耗大量时间以及CPU和内存等硬件资源

  • 易被攻击
    1、因为有确认机制,三次握手等机制,容易被人利用,实现DOS 、DDOS攻击

如何保证接收的顺序性:


TCP协议使用SEQ和ACK机制保证了顺序性
TCP的每个报文都是有序号的。确认应答信号ACK=收到的SEQ+1

【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说”我Client端没有数据要发给你了”,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,”告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息”。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,”告诉Client端,好了,我这边数据发完了,准备好关闭连接了”。Client端收到FIN报文后,”就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,”就知道可以断开连接了”。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

整个过程Client端所经历的状态如下:

而Server端所经历的过程如下:

【注意】 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。

UDP协议



  • User Data Protocol,用户数据包协议
  • 面向无连接的协议
  • UDP报头只有8字节

简介:


  • 传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快的把它扔到网络上
  • 在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制
  • 在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段
  • 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息
  • UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小
  • 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制
  • UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表。
  • UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

优点:


  • 传输速率快
    1、传输数据前,不需要像TCP一样建立连接
    2、传输数据时,没有确认、窗口、重传、拥塞控制等机制

  • 较安全
    1、由于没有了TCP的一些机制,被攻击者利用的漏洞就少了

缺点:


  • 不可靠,不稳定
    1、由于没有了TCP的机制,在数据传输时如果网络不好,很可能丢包

用UDP协议通讯时怎样得知目标机是否获得了数据包


仿造TCP的做法,每发一个UDP包,都在里面加一个SEQ序号,接收方收到包后,将SEQ序号回复给发送方。如果发送方在指定时间以内没有收到回应,说明丢包了。

TCP与UDP的区别







































TCP面向有链接的通信服务 UDP面向无连接的通信服务
TCP提供可靠的通信传输 UDP不可靠,会丢包
TCP保证数据顺序 UDP不保证
TCP数据无边界 UDP有边界
TCP速度快 UDP速度慢
TCP面向字节流 UDP面向报文
TCP一对一 UDP可以一对一,一对多
TCP报头至少20字节 UDP报头8字节
TCP有流量控制,拥塞控制 UDP没有

问题

为什么UDP比TCP快


  1. TCP需要三次握手
  2. TCP有拥塞控制,控制流量等机制

为什么TCP比UDP可靠


  1. TCP是面向有连接的,建立连接之后才发送数据;而UDP则不管对方存不存在都会发送数据。
  2. TCP有确认机制,接收端每收到一个正确包都会回应给发送端。超时或者数据包不完整的话发送端会重传。UDP没有。因此可能丢包。

什么时候使用TCP


当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。
在日常生活中,常见使用TCP协议的应用如下:
浏览器,用的HTTP
FlashFXP,用的FTP
Outlook,用的POP、SMTP
Putty,用的Telnet、SSH
QQ文件传输

什么时候应该使用UDP:


当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。
比如,日常生活中,常见使用UDP协议的应用如下:
QQ语音
QQ视频
TFTP

TCP无边界,UDP有边界


TCP无边界

客户端分多次发送数据给服务器,若服务器的缓冲区够大,那么服务器端会在客户端发送完之后一次性接收过来,所以是无边界的;

UDP有边界

客户端每发送一次,服务器端就会接收一次,也就是说发送多少次就会接收多少次,因此是有边界的。

为什么连接的时候是三次握手,关闭的时候是四次握手?


因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次握手

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?


虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态是用来重发可能丢失的ACK报文。