Kubernetes跨主机通信时的注意事项

我们知道docker的两个主机之间容器是不能直接通讯的,Kubernetes也没有自带解决这个问题,

部署Kubernetes的时候大多使用flannel或者calico插件带来的解决方案,

本文不对这两个解决方案做对比,这是你在选择前应该自己去了解的。本文旨在填网络部分的坑

接受所有ip的数据包转发

新建文件/etc/systemd/system/docker.service.d/iptables.conf并填入以下内容保存

[Service]

ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT

这样不同主机都能直接访问到pod的网络了

使用内网穿透技术映射主机端口到公网

内网穿透的技术有很多,常用的方法有:

  • ssh/autossh
  • ngfork
  • frp (本文将介绍该方法)

github地址:https://github.com/fatedier/frp

frp为传统的C/S结构,可分为客户端和服务端,其中

  • frpc(客户端) 运行在内网环境
  • frps(服务端)运行在有公网IP的服务器

编写frpc.ini文件,例如:

[common] server_addr = 公网IP server_port = frps运行的端口 token = 一串随机字符用来防止未经授权的使用  [appName] type = tcp local_ip = 127.0.0.1 local_port = 需要映射的本地端口 remote_port = 映射成公网服务器的端口

服务器端frps.ini就更简单了

[common] bind_port = 服务端运行的端口 token = 一串随机字符用来防止未经授权的使用 ;允许被使用的端口范围 allow_ports = 40000-50000 

假设frps 运行在 1.2.3.4:34567,客户端(192.168.1.5)把本机的80端口映射成了38888端口,则链路如下

192.168.1.5:80 <-> 1.2.3.4:34567 <-> 1.2.3.4:38888

提高映射服务可靠性

请使用supervisor分配守护frpc/frps即可达到理想可靠性

 

 

策略路由 – 让你的服(ti)务(zi)器用两条腿走路

对于PC来说,一台电脑一般最多就两张网卡(有线+无线)。只要能上网,哪管是走的哪张网卡。然鹅,对于服务器来说,N多张网卡(N > 2)是正常不过的事情,如何在多网卡多网关下正常、合理地工作,这就就需要各种交换机以及本文的策略路由来配合了。

  • 首先来科普下 策略路由路由策略 的区别。

路由策略。(Route-Policy)
路由策略是通过修改路由表的路由条目来控制数据流量的可达性。即对接受和发布的路由进过滤。这种方式称为路由策略

策略路由。(Traffic-Policy)
策略路由是通过用户制定的策略进行转发,且该策略优于路由表的转发。这种方式称为策略路由
由此可知,路由策略是基于路由表进行流量的转发,而策略路由是基于策略进行流量的转发。两者都为了控制网络流量的可达性或调整网络流量的路径。

  • 首先来张图,介绍下本文的网络环境

服务器有两个网口,eth0和eth1

eth0 : 地址10.16.0.5 ,网关 10.16.0.1 ,掩码 255.255.255.0,对应公网IP 1.2.3.4

eth1 : 地址10.16.254.5,网关10.16.254.1,掩码255.255.255.0,对应公网IP 5.6.7.8

  • 正式开始:
  1. 修改/etc/iproute2/rt_tables文件,追加以下两行
252  e0
251  e1

解释:这里我们自定义了两个策略路由表,假设e0对应eth0,e1对应eth1,以便操作

2.编辑启动脚本 /etc/rc.local,增加下面内容

ip route flush table e0
ip route add default via 10.16.0.1 dev eth0 src 10.16.0.5 table e0
ip rule add from 10.16.0.1 table e0

ip route flush table e1
ip route add default via 10.16.254.1 dev eth1 src 10.16.254.5 table e1
ip rule add from 10.16.254.5 table e1

OK,理论上重启后服务器就能被不同的IP访问到并正常收发数据

然鹅too young,第2中rc.local这种N多年的老掉牙的东东,一点也不好用,时灵时不灵的,而且一点也不优雅(rc.local万金油时代已经过去了_(:з」∠)_

3.现代化的网络管理,当然是得用network或者NetworkManager啦,无视第二步,我们继续来

(1)新增 /etc/sysconfig/network-scripts/rule-eth0 文件,增加以下内容

from 10.16.0.5 table e0

(2)新增 /etc/sysconfig/network-scripts/rule-eth1 文件,增加以下内容

from 10.16.254.5 table e1

(3)编辑或新增 /etc/sysconfig/network-scripts/route-eth0 文件,增加以下内容

10.16.0.0/24 dev eth0 src 10.16.0.5 table e0
default via 10.16.0.1 table e0

(4)编辑或新增 /etc/sysconfig/network-scripts/route-eth1 文件,增加以下内容

10.16.254.0/24 dev eth1 src 10.16.254.5 table e1
default via 10.16.254.1 table e1

至此大功告成,service network restart 重启网络体验一下

At last,你说不知道服务器访问外网默认走哪个网关?骚年,给你的网卡加个Metric,爱往哪走往哪走~

参考资料:《CentOS双线双IP配置

ポリシーベースルーティングの設定について

(杂篇)几个概念说明

用户空间与内核空间


现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。

进程切换


为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:
1. 保存处理机上下文,包括程序计数器和其他寄存器。
2. 更新PCB信息。
3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
4. 选择另一个进程执行,并更新其PCB。
5. 更新内存管理的数据结构。
6. 恢复处理机上下文。

注:总而言之就是很耗资源,具体的可以参考这篇文章:进程切换

进程的阻塞


正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。当进程进入阻塞状态,是不占用CPU资源的

文件描述符fd


文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

缓存 I/O


缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。

缓存 I/O 的缺点:
数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。

Q&A:为何选择Netty

1.Netty 是什么?

Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。

2.使用 Netty 能够做什么?

  • 开发异步、非阻塞的 TCP 网络应用程序;
  • 开发异步、非阻塞的 UDP 网络应用程序;
  • 开发异步文件传输应用程序;
  • 开发异步 HTTP 服务端和客户端应用程序;
  • 提供对多种编解码框架的集成,包括谷歌的 Protobuf、JBoss Marshalling、Java 序列化、压缩编解码、XML 解码、字符串编解码等,这些编解码框架可以被用户直接使用;
    提供形式多样的编解码基础类库,可以非常方便的实现私有协议栈编解码框架的二次定制和开发;
  • 基于职责链模式的 Pipeline-Handler 机制,用户可以非常方便的对网络事件进行拦截和定制;
  • 所有的 IO 操作都是异步的,用户可以通过 Future-Listener 机制主动 Get 结果或者由IO 线程操作完成之后主动 Notify 结果,用户的业务线程不需要同步等待;
  • IP 黑白名单控制;
  • 打印消息码流;
  • 流量控制和整形;
  • 性能统计;
  • 基于链路空闲事件检测的心跳检测…

3.Netty 在哪些行业得到了应用?

互联网行业
随着网站规模的不断扩大,系统并发访问量也越来越高,传统基于 Tomcat 等 Web 容器的垂直架构已经无法满足需求,需要拆分应用进行服务化,以提高开发和维护效率。从组网情况看,垂直的架构拆分之后,系统采用分布式部署,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。

典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。

游戏行业
无论是手游服务端、还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈,非常方便定制和开发私有协议栈。

大数据领域
经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨节点通信,它的 Netty Service 基于 Netty 框架二次封装实现。
大数据计算往往采用多个计算节点和一个/N个汇总节点进行分布式部署,各节点之间存在海量的数据交换。由于 Netty 的综合性能是目前各个成熟 NIO 框架中最高的,因此,往往会被选中用作大数据各节点间的通信。

4.使用传统的 Socket 开发挺简单的,我为什么要切换到 NIO 进行编程呢?

首先我们看下传统基于同步阻塞 IO(BIO)的线程模型图:

由上图我们可以看出,传统的同步阻塞 IO 通信存在如下几个问题:

  • 线程模型存在致命缺陷:一连接一线程的模型导致服务端无法承受大量客户端的并发连接;
  • 性能差:频繁的线程上下文切换导致 CPU 利用效率不高;
  • 可靠性差:由于所有的 IO 操作都是同步的,所以业务线程只要进行 IO 操作,也会存在被同步阻塞的风险,这会导致系统的可靠性差,依赖外部组件的处理能力和网络的情况。
  • 采用非阻塞 IO(NIO)之后,同步阻塞 IO 的三个缺陷都将迎刃而解:
  • Nio 采用 Reactor 模式,一个 Reactor 线程聚合一个多路复用器 Selector,它可以同时注册、监听和轮询成百上千个 Channel,一个 IO 线程可以同时并发处理N个客户端连接,线程模型优化为1:N(N < 进程可用的最大句柄数)或者 M : N (M通常为 CPU 核数 + 1, N < 进程可用的最大句柄数);
  • 由于 IO 线程总数有限,不会存在频繁的 IO 线程之间上下文切换和竞争,CPU 利用率高;
  • 所有的 IO 操作都是异步的,即使业务线程直接进行 IO 操作,也不会被同步阻塞,系统不再依赖外部的网络环境和外部应用程序的处理性能。

由于切换到 NIO 编程之后可以为系统带来巨大的可靠性、性能提升,所以,目前采用 NIO 进行通信已经逐渐成为主流。

5.为什么不直接基于 JDK 的 NIO 类库编程呢?

我们通过 JDK NIO 服务端和客户端的工作时序图来回答下这个问题

 

即便抛开代码和 NIO 类库复杂性不谈,一个高性能、高可靠性的 NIO 服务端开发和维护成本都是非常高的,开发者需要具有丰富的 NIO 编程经验和网络维护经验,很多时候甚至需要通过抓包来定位问题。也许开发出一套 NIO 程序需要 1 个月,但是它的稳定很可能需要 1 年甚至更长的时间,这也就是为什么我不建议直接使用 JDK NIO 类库进行通信开发的一个重要原因。

下面再一起看下 JDK NIO 客户端的通信时序图(它同样非常复杂)

 

6.为什么要选择 Netty 框架?

Netty 是业界最流行的 NIO 框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,它已经得到成百上千的商用项目验证,例如 Hadoop 的 RPC 框架 Avro 使用 Netty 作为通信框架。很多其它业界主流的 RPC 和分布式服务框架,也使用 Netty 来构建高性能的异步通信能力。

Netty 的优点总结如下:

  • API 使用简单,开发门槛低;
  • 功能强大,预置了多种编解码功能,支持多种主流协议;
  • 定制能力强,可以通过 ChannelHandler 对通信框架进行灵活的扩展;
  • 性能高,通过与其它业界主流的 NIO 框架对比,Netty 的综合性能最优;
  • 社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会被加入;
  • 经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它完全满足不同行业的商用标准。

(转载)TCP的粘包现象

原博文链接:TCP的粘包现象

今天被阿里面到了TCP粘包的问题,一时答不上来非常尴尬,收集下别人的回答做个笔记。

1 什么是粘包现象

TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

2 为什么出现粘包现象

(1)发送方原因

我们知道,TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。

所以,正是Nagle算法造成了发送方有可能造成粘包现象。

(2)接收方原因

TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。

3 什么时候需要处理粘包现象

(1)如果发送方发送的多个分组本来就是同一个数据的不同部分,比如一个很大的文件被分成多个分组发送,这时,当然不需要处理粘包的现象;

(2)但如果多个分组本毫不相干,甚至是并列的关系,我们就一定要处理粘包问题了。比如,我当时要接收的每个分组都是一个有固定格式的商品信息,如果不处理粘包问题,每个读进来的分组我只会处理最前边的那个商品,后边的就会被丢弃。这显然不是我要的结果。

4 如何处理粘包现象

(1)发送方

对于发送方造成的粘包现象,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法。

(2)接收方

遗憾的是TCP并没有处理接收方粘包现象的机制,我们只能在应用层进行处理。

(3)应用层处理

应用层的处理简单易行!并且不仅可以解决接收方造成的粘包问题,还能解决发送方造成的粘包问题。

解决方法就是循环处理:应用程序在处理从缓存读来的分组时,读完一条数据时,就应该循环读下一条数据,直到所有的数据都被处理;但是如何判断每条数据的长度呢?

两种途径:

1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;

2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。

当时在做购物车的时候,我最开始的做法是设置开始符(0x7e)和结束符(0xe7),但在测试大量数据的时候,发现了数据异常。正如我所猜测,在调试过程中发现某些数据内部包含了它们。因为要处理的数据是量非常庞大,为做到万无一失,最后我采用了发送长度的方式。再也没有因为粘包而出过问题。

计算机网络知识点总结

  • OSI,TCP/IP,五层协议的体系结构,以及各层协议

应用层:提供用户与网络间的接口。—-HTTP、FTP、SMTP

运输层:进程到进程间的数据传输。—TCP、UDP

网络层:主机到主机之间的数据传输。—IP、选路协议

数据链路层:相邻结点之间的数据传输。—PPP、以太网

物理层:在物理介质上传输比特流。

应用层———PDU是报文(message)
传输层———PDU是数据段(segment)
网络层———PDU是数据报(datagram)
数据链路层—–PDU是数据帧(frame)
物理层———PDU是比特(bit)

  • PING操作的原理

使用ICMP,在IP主机、路由器之间传递控制消息

  • HTTP1.0/1.1区别

HTTP1.1中才有cache-control响应头,主要用于控制信息在浏览器的缓存

1. HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。

缺陷:访问一个包含有许多图像的网页文件的整个过程包含了多次请求和响应,每次请求和响应都需要建立一个单独的连接,每次连接只是传输一个文档和图像,器端每次建立和关闭连接却是一个相对比较费时的过程,并且会严重影响客户机和服务器的性能。

2. HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果。
HTTP 1.1还提供了Host、身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。

  • IP地址分类

A类地址:以0开头, 第一个字节范围:0~126(1.0.0.0 – 126.255.255.255);
B类地址:以10开头, 第一个字节范围:128~191(128.0.0.0 – 191.255.255.255);
C类地址:以110开头, 第一个字节范围:192~223(192.0.0.0 – 223.255.255.255);
10.0.0.0—10.255.255.255, 172.16.0.0—172.31.255.255, 192.168.0.0—192.168.255.255。(Internet上保留地址用于内部)
IP地址与子网掩码相得到网络号

  • ARP是地址解析协议,简单语言解释一下工作原理。

1:首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系
2:当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机IP地址,源主机MAC地址,目的主机的IP地址。
3:当本网络的所有主机收到该ARP数据包时,首先检查数据包中的目的IP地址是否是自己的IP地址,如果不是,则忽略该数据包;如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果已经存在,则覆盖,然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址。
4:源主机收到ARP响应包后。将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
广播发送ARP请求,单播发送ARP响应。

各种协议的介绍

  ICMP协议:因特网控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。
  TFTP协议:是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。
  HTTP协议:超文本传输协议,是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
  NAT协议:网络地址转换属接入广域网(WAN)技术,是一种将私有(保留)地址转化为合法IP地址的转换技术,
  DHCP协议:动态主机配置协议,一个局域网的网络协议,使用UDP协议工作,用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。

  • 描述RARP协议

RARP是逆地址解析协议,作用是完成硬件地址到IP地址的映射,主要用于无盘工作站,因为给无盘工作站配置的IP地址不能保存。工作流程:在网络中配置一台RARP服务器,里面保存着IP地址和MAC地址的映射关系,当无盘工作站启动后,就封装一个RARP数据包,里面有其MAC地址,然后广播到网络上去,当服务器收到请求包后,就查找对应的MAC地址的IP地址装入响应报文中发回给请求者。因为需要广播请求报文,因此RARP只能用于具有广播能力的网络。

  • 易混淆的协议所在层

ARP、RARP:属于网络层,工作在数据链路层。

ICMP:网络层

  • 在浏览器中输入www.baidu.com后执行的全部过程

1、客户端浏览器通过DNS解析到www.baidu.com的IP地址220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到220.161.27.48,然后通过TCP进行封装数据包,输入到网络层。
2、在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口,如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口。然后使用IP层的IP地址查找目的端。
3、客户端的网络层不用关心应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。
4、客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。

  • TCP三次握手和四次挥手的全过程

三次握手:
第一次握手:客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

四次挥手
与建立连接的“三次握手”类似,断开一个TCP连接则需要“四次握手”。
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

  • TCP和UDP的区别?

TCP提供面向连接的、可靠的数据流传输,而UDP提供的是非面向连接的、不可靠的数据流传输。
TCP传输单位称为TCP报文段,UDP传输单位称为用户数据报。
TCP注重数据安全性,UDP数据传输快,因为不需要连接等待,少了许多操作,但是其安全性却一般。
TCP对应的协议和UDP对应的协议

TCP对应的协议:
(1)FTP:定义了文件传输协议,使用21端口。
(2)Telnet:一种用于远程登陆的端口,使用23端口,用户可以以自己的身份远程连接到计算机上,可提供基于DOS模式下的通信服务。
(3)SMTP:邮件传送协议,用于发送邮件。服务器开放的是25号端口。
(4)POP3:它是和SMTP对应,POP3用于接收邮件。POP3协议所用的是110端口。
(5)HTTP:是从Web服务器传输超文本到本地浏览器的传送协议。

UDP对应的协议:
(1) DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。
(2) SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。
(3) TFTP(Trival File Transfer Protocal),简单文件传输协议,该协议在熟知端口69上使用UDP服务。

  • TCP的三次握手过程?为什么会采用三次握手,若采用二次握手可以吗?

建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。

(1)TCP的三次握手过程:主机A向B发送连接请求;主机B对收到的主机A的报文段进行确认;主机A再次对主机B的确认进行确认。
(2)采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。失效的连接请求报文段是指:主机A发出的连接请求没有收到主机B的确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。
(3)采用两次握手不行,原因就是上面说的失效的连接请求的特殊情况。

  • IP层为什么不对数据部分进行差错校验?
  因为网络层是“尽最大努力完整的传输数据包”,差错检测已由数据链路层实现,IP层没必要再进行一次校验。
  优点就是,因为不负责差错检测和纠错,所以可获得较高的传输性能。
  缺点就是,因为IP层不负责差错检测,那么错误检测只能在传输层或应用层被发现,使纠正错误的时间增加了。
  试想一下,如果两台PC跨INTERNET通信,之间隔了很多台路由器,PC1给PC2发了个数据包,到达第一台路由器后,在转发的过程中,数据包发生了错误:
  1-因为IP层不做差错校验,所以第2台路由器通过广域网协议(HDLC、PPP等)收到数据后,只要数据链路层正常,它就无法得知收到的IP包是否正确,错误就会这么传递下去,至到PC2才被发现。
  2-如果IP可以实现差错校验的功能,那么到了第2台路由器时,路由器2就不会再继续发错误包了,错误就会终止。
  不过现在网络传输的误码率都极低,所以IP层没必要再做一次校验!