Linux网络编程—传输层协议UDP和TCP

第一章:传输层

负责数据能够从发送端传输接收端。

第二章:再谈端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序;

在TCP/IP协议中,用"源IP"、"源端口号"、"目的IP"、"目的端口号"、"协议号"这样一个五元组来标识一个通信(可以通过netstat -n查看);

端口号范围划分

  • 0 - 1023:知名端口号。HTTP、FTP、SSH等这些广泛使用的应用层协议,它们的端口号都是固定的。
  • 1024 - 65535:操作系统动态分配的端口号。客户端程序的端口号,就是由操作系统从这个范围分配的。

认识知名端口号(Well-Know Port Number)

有些服务器是非常常用的,为了使用方便,人们约定一些常用的服务器,都是使用以下这些固定的端口号:

  • ssh服务器,使用22端口
  • ftp服务器,使用21端口
  • telnet服务器,使用23端口
  • http服务器,使用80端口
  • https服务器,使用443端口

执行下面的命令,可以看到知名端口号:

bash 复制代码
cat /etc/services

我们自己写一个程序使用端口号时,要避开这些知名端口号。

两个问题:

  1. 一个进程是否可以bind多个端口号?可以

  2. 一个端口号是否可以被多个进程bind?不可以

第三章:UDP协议

UDP协议段格式

  • 16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度;
  • 如果校验和出错,就会直接丢弃;

UDP的特点

UDP传输的过程类似于寄信。

  • 无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接;
  • 不可靠:没有确认机制,没有重传机制;如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息;
  • 面向数据报:不能够灵活的控制读写数据的次数和数量;

面向数据报

应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并;

用UDP传输100个字节的数据:

  • 如果发送端调用一次sendto,发送100个字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节;而不能循环调用10次recvfrom,每次接收10个字节;

UDP的缓冲区

  • UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;
  • UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃;

UDP的socket既能读, 也能写, 这个概念叫做 全双工

UDP使用注意事项

我们注意到,UDP协议首部中有一个16位的最大长度。也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)。

然而64K在当今的互联网环境下,是一个非常小的数字。

如果我们需要传输的数据超过64K,就需要在应用层手动分包,多次发送,并在接收端手动拼装;

基于UDP的应用层协议

  • NFS:网络文件系统
  • TFTP:简单文件传输协议
  • DHCP:动态主机配置协议
  • BOOTP:启动协议(用于无盘设备启动)
  • DNS:域名解析协议

当然,也包括你自己写UDP程序时自定义的应用层协议;

第四章:传输层协议TCP

TCP协议

TCP全称为"传输控制协议(Transmission Control Protocol)"。人如其名,要对数据的传输进行一个详细的控制;

TCP协议段格式

  • 源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
  • 32位序号/32位确认号:后面详细讲;
  • 4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
  • 6位标志位:
    • URG:紧急指针是否有效
    • ACK:确认号是否有效
    • PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
    • RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
    • SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
    • FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
  • 16位窗口大小:后面再说
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。
  • 16位紧急指针:标识哪部分数据是紧急数据;
  • 40字节头部选项:暂时忽略;

确认应答(ACK)机制

TCP将每个字节的数据都进行了编号,即为序列号。

每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

超时重传机制

  • 主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发;

但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了;

因此主机B会收到很多重复数据。那么TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉。

这时候我们可以利用前面提到的序列号,就可以很容易做到去重的效果。

那么,如果超时的时间如何确定?

  • 最理想的情况下,找到一个最小的时间,保证"确认应答一定能在这个时间内返回"。
  • 但是这个时间的长短,随着网络环境的不同,是有差异的。
  • 如果超时时间设得太长,会影响整体的重传效率;
  • 如果超时时间设得太短,有可能会频繁发送重复的包。

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。

  • Linux中(BSD Unix和Windows也是如此),超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
  • 如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。
  • 如果仍然得不到应答,等待 4*500ms 进行重传。依次类推,以指数形式递增。
  • 累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接。

数据发出但没有收到应答,不知道是否为丢包(也有可能阻塞在某条路径)。主机对于发出去的报文,是否丢失,无法判定。必须通过规定,表征是否要重传。如果应答丢失,会收到重复报文。去重,报文有序号

连接管理机制

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接。

服务端状态转化:

  • CLOSED -\> LISTEN\] 服务器端调用listen后进入LISTEN状态,等待客户端连接;

  • SYN_RCVD -\> ESTABLISHED\] 服务器端一旦收到客户端的确认报文,就进入ESTABLISHED状态,可以进行读写数据了。

  • CLOSE_WAIT -\> LAST_ACK\] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据);当服务器真正调用close关闭连接时,会向客户端发送FIN,此时服务器进入LAST_ACK状态,等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)

客户端状态转化:

  • CLOSED -\> SYN_SENT\] 客户端调用connect,发送同步报文段;

  • ESTABLISHED -\> FIN_WAIT_1\] 客户端主动调用close时,向服务器发送结束报文段,同时进入FIN_WAIT_1;

  • FIN_WAIT_2 -\> TIME_WAIT\] 客户端收到服务器发来的结束报文段,进入TIME_WAIT,并发出LAST_ACK;

对于服务器,listen的第二个参数设置为1,并且不调用accept。

客户端状态正常,但是服务器端出现了SYN_RECV状态,而不是ESTABLISHED状态。

这是因为,Linux内核协议栈为一个tcp连接管理使用两个队列:

  1. 半连接队列(用来保存处于SYN_SENT和SYN_RECV状态的请求)
  2. 全连接队列(accepted队列)(用来保存处于established状态,但是应用层没有调用accept取走的请求)

而全连接队列的长度会受到listen第二个参数的影响。

全连接队列满了的时候,就无法继续让当前连接的状态进入established状态了。

这个队列的长度通过上述实验可知,是listen的第二个参数 + 1。

理解TIME_WAIT状态

现在做一个测试,首先启动server,然后启动client,然后用Ctrl-C使server终止,这时马上再运行server,结果是:

这是因为,虽然server的应用程序终止了,但TCP协议层的连接并没有完全断开,因此不能再次监听同样的server端口。我们用netstat命令查看一下:

  • TCP协议规定,主动关闭连接的一方要处于TIME_WAIT状态,等待两个MSL(maximum segment lifetime)的时间后才能回到CLOSED状态。
  • 我们使用Ctrl-C终止了server,所以server是主动关闭连接的一方,在TIME_WAIT期间仍然不能再次监听同样的server端口;
  • MSL在RFC1122中规定为两分钟,但是各操作系统的实现不同,在Centos7/Ubuntu上默认配置的值是60s;
  • 可以通过 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看msl的值;
  • 规定TIME_WAIT的时间请读者参考UNP 2.7节;

想一想,为什么TIME_WAIT的时间是2MSL?

  • MSL是TCP报文的最大生存时间,因此TIME_WAIT持续存在2MSL的话
  • 就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启,可能会收到来自上一个进程的迟到的数据,但是这种数据很可能是错误的);
  • 同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失,那么服务器会再重发一个FIN。这时虽然客户端的进程不在了,但是TCP连接还在,仍然可以重发LAST_ACK);

解决TIME_WAIT状态引起的bind失败的方法

在server的TCP连接没有完全断开之前不允许重新监听,某些情况下可能是不合理的。

  • 服务器需要处理非常大量的客户端的连接(每个连接的生存时间可能很短,但是每秒都有很大数量的客户端来请求)。
  • 这个时候如果由服务器端主动关闭连接(比如某些客户端不活跃,就需要被服务器端主动清理掉),就会产生大量TIME_WAIT连接。
  • 由于我们的请求量很大,就可能导致TIME_WAIT的连接数很多,每个连接都会占用一个通信五元组(源ip,源端口,目的ip,目的端口,协议)。其中服务器的ip和端口和协议是固定的。如果新来的客户端连接的ip和端口号和TIME_WAIT占用的连接重复了,就会出现问题。

使用setsockopt()设置socket描述符的选项SO_REUSEADDR为1,表示允许创建端口号相同但IP地址不同的多个socket描述符。

SO_REUSEADDR的核心作用是:允许重用处于TIME_WAIT状态的本地地址(IP:端口)
更准确的说法应该是:允许绑定一个已经被占用(特别是处于TIME_WAIT状态)的地址

bash 复制代码
tcp 0 0 0.0.0.0:9090 0.0.0.0:* LISTEN
5038/./dict_server
tcp 0 0 127.0.0.1:49958 127.0.0.1:9090 FIN_WAIT2
-
tcp 0 0 127.0.0.1:9090 127.0.0.1:49958
CLOSE_WAIT 5038/./dict_server

理解 CLOSE_WAIT 状态

以之前写过的TCP服务器为例,我们稍加修改

将sockfd.Close();这个代码去掉。

我们编译运行服务器。启动客户端链接,查看TCP状态,客户端服务器都为ESTABLISHED状态,没有问题。

然后我们关闭客户端程序,观察TCP状态

此时服务器进入了CLOSE_WAIT状态,结合我们四次挥手的流程图,可以认为四次挥手没有正确完成。

小结:

对于服务器上出现大量的CLOSE_WAIT状态,原因就是服务器没有正确的关闭socket,导致四次挥手没有正确完成。这是一个BUG。只需要加上对应的close即可解决问题。

滑动窗口

刚才我们讨论了确认应答策略,对每一个发送的数据段,都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。

既然这样一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大提高性能(其实是将多个段的等待时间重叠在一起了)。

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段)。
  • 发送前四个段的时候,不需要等待任何ACK,直接发送;
  • 收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
  • 操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;
  • 窗口越大,则网络的吞吐率就越高;

那么如果出现了丢包,如何进行重传?这里分两种情况讨论。

情况一:数据包已经抵达,ACK被丢了。

这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认;

情况二:数据包就直接丢了。

  • 当某一段报文段丢失之后,发送端会一直收到1001这样的ACK,就像是在提醒发送端"我想要的是1001"一样;
  • 如果发送端主机连续三次收到了同一个"1001"这样的应答,就会将对应的数据1001-2000重新发送;
  • 这个时候接收端收到了1001之后,再次返回的ACK就是7001了(因为2001-7000接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中);

这种机制被称为"高速重发控制"(也叫"快重传")

流量控制

接收端处理数据的速度是有限的。如果发送端发得太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。

  • 因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control);
  • 接收端将自己可以接收的缓冲区剩余空间大小放入TCP首部中的"窗口大小"字段,通过ACK端通知发送端;
  • 窗口大小字段越大,说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接受到这个窗口之后,就会减慢自己的发送速度;
  • 如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

接收端如何把窗口大小告诉发送端呢?回忆我们的TCP首部中,有一个16位窗口字段,就是存放了窗口大小信息;

那么问题来了,16位数字最大表示65535,那么TCP窗口最大就是65535字节么?

实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位;

拥塞控制

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。

因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。

TCP引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

  • 此处引入一个概念称为拥塞窗口;
  • 发送开始的时候,定义拥塞窗口大小为1;
  • 每次收到一个ACK应答,拥塞窗口加1;
  • 每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口;

像上面这样的拥塞窗口增长速度,是指数级别的。"慢启动"只是指初始时慢,但是增长速度非常快。

  • 为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。
  • 此处引入一个叫做慢启动的阈值。
  • 当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。
  • 当TCP开始启动的时候,慢启动阈值等于窗口最大值;
  • 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1;

少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;

当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;

拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

TCP拥塞控制这样的过程,就好像热恋的感觉。

延迟应答

如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。

  • 假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;
  • 但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来;
  • 如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M;

一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

那么所有的包都可以延迟应答么?肯定也不是;

  • 数量限制:每隔N个包就应答一次;
  • 时间限制:超过最大延迟时间就应答一次;

具体的数量和超时时间,依操作系统不同也有差异;一般N取2,超时时间取200ms;

捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是"一发一收"的。意味着客户端给服务器说了"How are you",服务器也会给客户端回一个"Fine, thank you";

那么这个时候ACK就可以搭顺风车,和服务器回应的"Fine, thank you"一起回给客户端。

面向字节流

创建一个TCP的socket,同时在内核中创建一个发送缓冲区和一个接收缓冲区;

  • 调用write时,数据会先写入发送缓冲区中;
  • 如果发送的字节数太长,会被拆分成多个TCP的数据包发出;
  • 如果发送的字节数太短,就会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适的时机发送出去;
  • 接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区;
  • 然后应用程序可以调用read从接收缓冲区拿数据;
  • 另一方面,TCP的一个连接,既有发送缓冲区,也有接收缓冲区,那么对于这一个连接,既可以读数据,也可以写数据。这个概念叫做全双工。

由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:

  • 写100个字节数据时,可以调用一次write写100个字节,也可以调用100次write,每次写一个字节;
  • 读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100个字节,也可以一次read一个字节,重复100次;

粘包问题

  • 首先要明确,粘包问题中的"包",是指的应用层的数据包。
  • 在TCP的协议头中,没有如同UDP一样的"报文长度"这样的字段,但是有一个序号这样的字段。
  • 站在传输层的角度,TCP是一个一个报文过来的。按照序号排好序放在缓冲区中。
  • 站在应用层的角度,看到的只是一串连续的字节数据。
  • 那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个完整的应用层数据包。

那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界。

  • 对于定长的包,保证每次都按固定大小读取即可;例如上面的Request结构,是固定大小的,那么就从缓冲区从头开始按sizeof(Request)依次读取即可;
  • 对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置;
  • 对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序员自己来定的,只要保证分隔符不和正文冲突即可);

思考:对于UDP协议来说,是否也存在"粘包问题"呢?

  • 对于UDP,如果还没有上层交付数据,UDP的报文长度仍然在。同时,UDP是一个一个把数据交付给应用层。就有很明确的数据边界。
  • 站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收。不会出现"半个"的情况。

TCP异常情况

进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。

机器重启:和进程终止的情况相同。

机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在。如果对方不在,也会把连接释放。

另外,应用层的某些协议,也有一些这样的检测机制。例如HTTP长连接中,也会定期检测对方的状态。例如QQ,在QQ断线之后,也会定期尝试重新连接。

TCP小结

为什么TCP这么复杂?因为要保证可靠性,同时又尽可能的提高性能。

可靠性:

  • 校验和
  • 序列号(按序到达) 去重
  • 确认应答 核心
  • 超时重发
  • 连接管理
  • 流量控制
  • 拥塞控制

提高性能:

  • 滑动窗口
  • 快速重传
  • 延迟应答
  • 捎带应答

其他:

  • 定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)

基于TCP应用层协议

  • HTTP
  • HTTPS
  • SSH
  • Telnet
  • FTP
  • SMTP

当然,也包括你自己写TCP程序时自定义的应用层协议;

TCP/UDP对比

我们说了TCP是可靠连接,那么是不是TCP一定就优于UDP呢?TCP和UDP之间的优点和缺点,不能简单、绝对的进行比较。

  • TCP用于可靠传输的情况,应用于文件传输,重要状态更新等场景;
  • UDP用于对高速传输和实时性要求较高的通信领域,例如,早期的QQ,视频传输等。另外UDP可以用于广播。

归根结底,TCP和UDP都是程序员的工具,什么时机用,具体怎么用,还是要根据具体的需求场景去判定。

用UDP实现可靠传输(经典面试题)

参考TCP的可靠性机制,在应用层实现类似的逻辑;

例如:

  • 引入序列号,保证数据顺序;
  • 引入确认应答,确保对端收到了数据;
  • 引入超时重传,如果隔一段时间没有应答,就重发数据。

文件和socket的关系

文件描述符到socket的映射关系

第五章:网络层

在复杂的网络环境中确定一个合适的路径。

IP协议

基本概念

主机:配有IP地址,也要进行路由控制的设备;

路由器:即配有IP地址,又能进行路由控制;

节点:主机和路由器的统称;

协议头格式

  • 4位版本号(version):指定IP协议的版本,对于IPv4来说,就是4。
  • 4位头部长度(header length):IP头部的长度是多少个32bit,也就是length*4的字节数。4bit表示最大的数字是15,因此IP头部最大长度是60字节。
  • 8位服务类型(Type Of Service):3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对于ftp这样的程序,最大吞吐量比较重要。
  • 16位总长度(total length):IP数据报整体占多少个字节。
  • 16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。
  • 3位标志字段:第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了的话,最后一个分片置为0,其他是1。类似于一个结束标记。
  • 13位分片偏移(fragment offset):是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值*8得到的。因此,除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)。
  • 8位生存时间(Time To Live,TTL):数据报到达目的地的最大报文跳数。一般是64。每次经过一个路由,TTL -= 1,一直减到0还没到达,那么就丢弃了。这个字段主要是用来防止出现路由循环。
  • 8位协议:表示上层协议的类型。
  • 16位头部校验和:使用CRC进行校验,来鉴别头部是否损坏。
  • 32位源地址和32位目标地址:表示发送端和接收端。
  • 选项字段(不定长,最多40字节):略。

网段划分(重要)

IP地址分为两个部分,网络号和主机号

  • 网络号:保证相互连接的两个网段具有不同的标识;
  • 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号;
  • 不同的子网其实就是把网络号相同的主机放到一起。
  • 如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复。

通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的IP地址都不相同。

那么问题来了,手动管理子网内的IP,是一个相当麻烦的事情。

  • 有一种技术叫做DHCP,能够自动地给子网内新增主机节点分配IP地址,避免了手动管理IP的不便。
  • 一般的路由器都带有DHCP功能。因此路由器也可以看做一个DHCP服务器。

过去曾经提出一种划分网络号和主机号的方案,把所有IP地址分为五类,如下图所示(该图出自[TCP/IP])。

  • A类 0.0.0.0到127.255.255.255
  • B类 128.0.0.0到191.255.255.255
  • C类 192.0.0.0到223.255.255.255
  • D类 224.0.0.0到239.255.255.255
  • E类 240.0.0.0到247.255.255.255

随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址;

  • 例如,申请了一个B类地址,理论上一个子网内能允许6万5千多个主机。A类地址的子网内的主机数更多。
  • 然而实际网络架设中,不会存在一个子网内有这么多的情况。因此大量的IP地址都被浪费掉了。

针对这种情况提出了新的划分方案,称为CIDR(Classless Interdomain Routing)(无类别域间路由):

  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
  • 子网掩码也是一个32位的正整数。通常用一串"0"来结尾;
  • 将IP地址和子网掩码进行"按位与"操作,得到的结果就是网络号;
  • 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;

可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围;

IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68,子网掩码的高24位是1,也就是255.255.255.0。

特殊的IP地址

  • 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网;
  • 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包;
  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1。

IP地址的数量限制

我们知道,IP地址(IPv4)是一个4字节32位的正整数。那么一共只有2的32次方个IP地址,大概是43亿左右。而TCP/IP协议规定,每个主机都需要有一个IP地址。

这意味着,一共只有43亿台主机能接入网络么?

实际上,由于一些特殊的IP地址的存在,数量远不足43亿;另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址。

CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的绝对上限并没有增加),仍然不是很够用。这时候有三种方式来解决:

  • 动态分配IP地址:只给接入网络的设备分配IP地址。因此同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的;
  • NAT技术(后面会重点介绍);
  • IPv6:IPv6并不是IPv4的简单升级版。这是互不相干的两个协议,彼此并不兼容;IPv6用16字节128位来表示一个IP地址;但是目前IPv6还没有普及;

私有IP地址和公网IP地址

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址:

  • 10.*,前8位是网络号,共16,777,216个地址
  • 172.16.*到172.31.*,前12位是网络号,共1,048,576个地址
  • 192.168.*,前16位是网络号,共65,536个地址

包含在这个范围中的,都称为私有IP,其余的则称为全局IP(或公网IP)。

  • 一个路由器可以配置两个IP地址,一个是WAN口IP,一个是LAN口IP(子网IP)。
  • 路由器LAN口连接的主机,都从属于当前这个路由器的子网中。
  • 不同的路由器,子网IP其实都是一样的(通常都是192.168.1.1)。子网内的主机IP地址不能重复。但是子网之间的IP地址就可以重复了。
  • 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了。
  • 子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN口IP),这样逐级替换,最终数据包中的IP地址成为一个公网IP。这种技术称为NAT(Network Address Translation,网络地址转换)。
  • 如果我们希望自己实现的服务器程序,能够在公网上被访问到,就需要把程序部署在一台具有外网IP的服务器上。这样的服务器可以在阿里云/腾讯云上进行购买。

尝试理解公网

真实的网络结构非常复杂,既涉及到划分公网IP的组织------ICANN,还要在全球范围内进行区域划分,比如亚太、北美、欧洲等,又要考虑各个国家内部的ISP代理,整体拓扑非常复杂。我们简化所有过程,简单理解公网即可。

附录有关于建设公网的参与者,和职责说明,AI提示词:公网的整个构建过程,需要涉及到谁,各自核心角色和作用是什么?

路由

在复杂的网络结构中,找出一条通往终点的路线;

路由的过程,就是这样一跳一跳(Hop by Hop)"问路"的过程。

所谓"一跳"就是数据链路层中的一个区间。具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。

IP数据包的传输过程也和问路一样。

  • 当IP数据包到达路由器时,路由器会先查看目的IP;
  • 路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器;
  • 依次反复,一直到达到目标IP地址;

那么如何判定当前这个数据包该发送到哪里呢?这个就依靠每个节点内部维护一个路由表;

  • 路由表可以使用route命令查看。
  • 如果目的IP命中了路由表,就直接转发即可;
  • 路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址。

假设某主机上的网络接口配置和路由表如下:

  • 这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到192.168.56.0/24网络;
  • 路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。

转发过程例1:如果要发送的数据包的目的地址是192.168.56.3

  • 跟第一行的子网掩码做与运算得到192.168.56.0,与第一行的目的网络地址不符;
  • 再跟第二行的子网掩码做与运算得到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去;
  • 由于192.168.56.0/24正是与eth1接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发。

转发过程例2:如果要发送的数据包的目的地址是202.10.1.2

  • 依次和路由表前几项进行对比,发现都不匹配;
  • 按缺省路由条目,从eth0接口发出去,发往192.168.10.1路由器;
  • 由192.168.10.1路由器根据它的路由表决定下一跳地址。

作业

1. 【多选题】FTP服务的控制端口与数据端口默认是()

A.20

B.21

C.22

D.23

答案:AB

答案解析:

FTP协议中,20端口号用于传输数据,21端口号用于传输控制

  1. 下列TCP端口号中不属于熟知端口号的是()

A.21

B.23

C.80

D.3210

答案:D

答案解析

0~1023之间的端口都属于知名端口,保留给知名协议的对应服务。

  • 21 : 文件传输协议端口
  • 23 : telnet端口
  • 80 : http服务端口

因此正确选项为:D

3. 端口号是保留给常用的服务器应用程序的,也被称为熟知端口,其范围是( )

A.0~1024

B.0~1023

C.1~1024

D.1~1023

答案:B

答案解析

熟知(知名)端口范围:0~1023,通常这些端口号都是留给知名协议对应的服务的,比如HTTP服务默认使用80端口

4. 关于TCP和UDP说法错误的是()

A.TCP是面向连接的协议,UDP是无连接的协议

B.TCP和UDP消息到达网络另一端都是有序的

C.TCP速度比较慢,UDP速度比较快

D.UDP没有流量控制和拥塞控制

答案:B

答案解析

TCP协议特性: 面向连接,可靠传输,提供字节流传输服务。 它的传输安全性较高,保证数据能够安全有序到达对端,但是效率与UDP传输相比较低

UDP协议特性: 无连接,不可靠,提供数据报传输服务,它不保证可靠传输,只管快速的传输数据,安全性不如TCP,但是效率较高

A正确

B错误:UDP没有包序管理,不保证数据有序到达

C正确

D正确:流量控制和拥塞控制是TCP协议中为了避免因为意外情况而丢包重传的两种机制。

5. 关于UDP的说法正确的是()

A.UDP的包大小没有限制

B.UDP不会进行错误重传

C.UDP跟TCP一样提供可靠的数据报协议

D.UDP有简单的流控制

答案:B

答案解析

A错误:UDP报文协议字段中包含有2个字节大小的数据报大小字段,因为2字节能够存储的最大数字为65535,因此UDP报文限制传输报文大小为必须小于64k。

B正确:UDP传输,没有报文的丢包检测以及重传机制,数据报丢了就没了,以及数据出错也不会进行重传

C错误:UDP是不可靠传输,不保证数据安全及有序到达对端

D错误:UDP是数据报传输,没有流控制...

6. 【多选题】客户端主动断开TCP连接的时候,以下"四次挥手"过程中表述错误的是()

A.当Client收到Server的ACK包之后,Client状态变成FIN_WAIT2状态

B.当Server发送FIN包到Client之后,Client需要等待1MSL,状态才从TIME_WAIT状态变成CLOSED状态

C.Server端出现大量的CLOSE_WAIT状态,是由于Client没有及时的关闭连接

D."四次挥手"是完全没有必要的,"三次挥手"就可以了

答案:BCD

  • A正确
  • B错误:当Server发送FIN包到Client之后,Client需要等待2MSL,处理有可能因为最后一次ACK丢失导致的重传(重传的FIN是1MSL,自己发送的ACK是1MSL,共2MSL),最终状态才从TIME_WAIT状态变成CLOSED状态
  • C错误:CLOSE_WAIT状态是被动关闭方收到FIN并进行ACK回复后进入的状态,接下来他会等待上层知道对方要关闭连接后做出处理,当自己也要关闭连接的时候给对方发送FIN,则 进入LAST_ACK状态,而一旦自己上层没有做出处理,则套接字状态会一直处于CLOSE_WAIT, 因此Server端出现大量的CLOSE_WAIT,是由于Server端没有及时的关闭连接导致的。
  • D错误:这里需要了解FIN的功能,收到FIN只能表示对方不再给自己发送数据,而不是完全关闭既不发送数据也不再接收数据,他还是可以继续接收数据的,因此被动关闭方收到FIN请求进行ACK确认后,可能还会继续发送数据,直到自己也不再发送了,才会发送接下来的FIN包,因此四次挥手不能合并成为 三次挥手。

7. 【多选题】客户端主动断开TCP连接的时候,以下"四次挥手"过程中状态变迁表述正确的是()

A.Client发送一个FIN,用来关闭Client到Server之间的数据传输,Client进入FIN_WAIT1状态

B.Server收到了来自Client的FIN包,发送一个ack给client,进入CLOSE_WAIT状态

C.Server发送一个FIN,用来关闭Server到Client之间的数据传输,Server进入LAST_ACK状态

D.Client收到FIN包之后,Client发送一个ACK给Server, 紧接着进入TIME_WAIT状态,Server收到ack后进入CLOSED状态

答案:ABCD

四次挥手:

D : 这里是先进入time_wait 后发ack 还是先发ack后进入time_wait

8. TCP 三次握手的过程,accept 发生在三次握手哪个阶段?()

A.第一次握手

B.第二次握手

C.第三次握手

D.三次握手后

答案:D

答案解析:

accept函数的功能为:获取一个已经连接建立完成的socket套接字描述符,作为与指定客户端通信的句柄。

既然是已经连接建立完成,则accept发送在三次握手之后。

正确选项为:D

9. 下列哪项最恰当地描述了建立TCP连接时"第一次握手"所做的工作()

A."连接发起方"向"接收方"发送一个SYN - ACK段

B."接收方"向"连接发起方"发送一个SYN - ACK段

C."连接发起方"向目标主机的TCP进程发送一个SYN段

D."接收方"向源主机得到TCP进程发送一个SYN段作为应答

答案:C

答案解析

TCP三次握手过程:

第一次握手:客户端向服务器发送连接请求, 也就是SYN段

第二次握手:服务器向客户端发送确认回复及连接请求, 也就是 SYN + ACK段

第三次握手:客户端向服务器发送确认回复,也就是ACK段

基于以上理解,正确选项为:C

10. 主机甲向主机乙发送一个(SYN = 1, seq = 11220)的TCP段, 期望与主机乙建立TCP连接, 若主机乙接受该连接请求, 则主机乙向主机甲发送的正确的TCP段应该是()

A.(SYN = 1, ACK = 1, seq = 11220, ack = 11220)

B.(SYN = 1, ACK = 1, seq = 11221, ack = 11221)

C.(SYN = 0, ACK = 0, seq = 11221, ack = 11221)

D.(SYN = 0, ACK = 1, seq = 11220, ack = 11220)

答案:B

答案解析:

三次握手过程:

SYN和ACK是TCP协议报头中的6个保留位中的2位。

ACK:ACK位置为1表明确认号是合法的。如果ACK为0,那么数据报不包含确认信息,确认字段被省略。

seq:发送方的本条报文起始序号

ack:对于上次对方发送的数据的确认序号,通常是对方发送的数据的起始序号 + 数据长度,但是在三次握手阶段稍有不同,是上次对方发送的请求的起始序号 + 1

SYN = 1, seq = 11220, SYN = 1表示这是一个客户端的第一次握手连接建立请求, 并且起始序号为11220

服务器收到请求后,向客户端进行第二次握手,第二次握手既是自己的连接建立请求,也是对客户端连接请求的确认,因此 SYN = 1, ACK = 1, 而确认序号为对方的起始序号 + 1, 则为11221

则 SYN = 1, ACK = 1, ack = 11221, seq = 自己的起始序号,一般为随机值这个不做要求

则符合条件的只有B选项

11. 在TCP报文段中,接收窗口(receive window)字段用于()

A.可靠数据传输

B.延迟保证

C.流量控制

D.拥塞控制

答案:C

答案解析

通过接收窗口开确认对方是否收到请求报文,从而对流量进行控制

12. 主机甲和主机乙新建一个TCP 连接,甲的拥塞控制初始阈值为 32KB,甲向乙始终以 MSS = 1KB 大小的段发送数据, 并一直有数据发送;乙为该连接分配 16KB 接收缓存,并对每个数据段进行确认,忽略段传输延迟。若乙收到的数据全 部存入缓存,不被取走,则甲从连接建立成功时刻起,未发送超时 的情况下,经过 4 个 RTT 后,甲的发送窗口是 ()

A.1KB

B.8KB

C.16KB

D.32KB

答案:A

13. 以下关于TCP可靠性说法错误的是()

A.TCP能保证数据的正确性,无差错、不丢失、不重复、并且按序达到

B.三次握手和四次挥手也是TCP可靠性的保证

C.TCP的流量控制也是TCP可靠性的保证

D.以上说法都是不正确的

答案:D

答案解析

上述ABC选项都是TCP保证可靠性的机制,所以选D

14. TCP / IP 模型中哪一层处理传输的可靠性、流量控制和错误控制()

A.应用层(Application)

B.传输层(Transport)

C.互联网络层(Internet)

D.网络访问层(Network Access)

答案:B

答案解析

tcp协议完成可靠性,流量控制和错误控制,而tcp协议工作在传输层

15. TCP使用滑动窗口进行流量控制,流量控制实际上是对( )的控制

A.发送方数据流量

B.接收方数据流量

C.发送、接收方数据流量

D.链路上任意两节点间的数据流量

答案:A

答案解析

流量控制的原因是由于网络延时过大或者对端处理能力弱,而导致可能会发生拥塞,所以需要控制发送发的数据流量,从而和接收方的处理能力相匹配

16. TCP协议在建立连接的过程中可能处于不同的状态,用netstat命令显示出TCP连接的状态为SYN_SEND,则这个连接正处于()

A.监听对方的建立连接请求

B.已主动发出连接建立请求

C.等待对方的连接释放请求

D.收到对方的连接建立请求

答案:B

答案解析:SYN_SEND是属于请求连接,则先排除C,监听对方简历连接请求指的是服务端处于listen状态,排除A。接收到对方的连接建立请求,则应该处于SYN_RECEIVED

17. 以下不属于tcp连接断开的状态是()

A.TIME_WAIT

B.FIN_WAIT_1

C.SYNC_SENT

D.FIN_WAIT_2

答案:C

答案解析

SYNC_SENT是请求连接

18. TCP主动关闭一方进入最后的一个状态是()

A.CLOSE_WAIT

B.SYN_SENT

C.TIME_WAIT

D.LAST_ACK

答案:C

答案解析:

CLOSE_WAIT状态是接收到FIN报文时候的状态

SYN_SENT压根不是四次挥手当中的状态

TIME_WAIT是主动关闭乙方进入的最后一个状态,需要等待2MSL,状态才从TIME_WAIT状态变成CLOSED状态

LAST_ACK是被动方发送FIN报文之后置的状态

19. TCP 连接有多重状态,如何在系统中查看某个连接的状态 ?()

A.ping

B.netstat

C.ifconfig

D.traceroute

答案:B

答案解析

netstat可以查看系统当中连接的状态

eg : netstat - anp | grep[port]

20. 【多选题】TCP 状态变迁中,存在 TIME_WAIT 状态,请问以下正确的描述是?()

A.TIME_WAIT 状态可以帮助 TCP 的全双工连接可靠释放

B.TIME_WAIT 状态是 TCP 是三次握手过程中的状态

C.TIME_WAIT 状态是为了保证重新生成的 socket 不受之前延迟报文的影响

D.TIME_WAIT 状态是为了让旧数据包消失在网络中

答案:ACD

答案解析

TIME_WAIT 状态是 TCP 是四次挥手过程中的状态

21. 以下关于TCP粘包说法不正确的是()

A.可以使用短连接来解决TCP粘包的问题

B.关闭nagle算法一定能够解决TCP粘包问题

C.nagle算法其中之一的规则为:如果该包含有FIN,则允许发送

D.nagle算法可以很大程度的利用网络带宽

答案:B

答案解析

nagle算法只能缓解TCP粘包问题,不能根本解决

22. 以下哪种描述不可以缓解TCP粘包问题()

A.使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容

B.设置定长消息,服务端每次读取既定长度的内容作为一条完整消息,当消息不够长时,空位补上固定字符

C.设置消息边界,服务端从网络流中按消息编辑分离出消息内容,一般使用'\r\n'

D.以上的说法中A和B可以缓解,C不行

答案:D

答案解析

TCP粘包问题一般是由于缓冲区当中有不同的报文信息,当把缓冲区的数据发送到网络上的时候,就会产生粘包问题;粘包问题带来的问题是会导致对方收到网络上的数据的时候无法进行合理的拆包;所以,在处理粘包问题上,需要给每个报文设置明显的消息边界来进行区分;或者双方约定发送定长的消息;或者在应用层处理的时候加上数据报文头部

23. 【多选题】以下哪种情况下会可能会触发TCP粘包()

A.应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包

B.应用程序写入的数据大于套接字缓冲区大小,这将会发生粘包

C.接收方不及时读取套接字缓冲区数据,这将发生粘包

D.当应用程序数据长度 - TCP头部长度 > MSS的时候将发生粘包

答案:AC

答案解析

粘包的问题是指不同报文一起发送到网络上,则当写的缓冲区当中存在不同的报文的时候,就会发生粘包问题

所以排除B。对于接收方而言,如果数据已经到达缓冲区,但是不及时读取,则会导致后边的报文和前面的报文发生粘包问题;D选项,首先需要知道MSS是指的是Maximum Segment Size,TCP一次传输发送的最大数据段长度

所以D选项也是不会造成粘包问题的,故排除

24. 以下关于TCP连接异常描述错误的是()

A.若向已经接收到RST的sock继续写入数据,则内核会向该进程发送一个SIGPIPE信号,该信号默认为中止进程。且写操作返回错误EPIPE

B.服务器主机崩溃可能会导致read返回ETIMEOUT

C.服务器主机崩溃后重启后,客户端发送送数据时,不会受到RST报文

D.服务器主机主动关机,会导致连接发生异常

答案:C

答案解析:

服务器主机崩溃后重启后,客户端发送送数据时,会收到一个RST,则read返回ECONNREST

25. 以下情况下不一定出现TCP分节RST的情况是:()

A.服务器端端口未打开而客户端来连接时

B.SO_RCVTIMEO选项设置了超时时间并超时

C.服务器主机崩溃后重启

D.在一个已关闭的socket上收到数据

答案:C

答案解析:

四种情况会发送RST包:

1、端口未打开

2、请求超时

3、提前关闭

4、在一个已关闭的socket上收到数据

26. TCP数据包里的出现什么标志位表示连接被异常终止,或被拒绝的异常请求()

A.FIN / ACK

B.RST / ACK

C.SYN

D.ACK

答案:B

答案解析

在TCP的报文头部,有6个标志位,其中RST表示重置连接,也是区分与正常连接标志的

27. 下面关于int listen(SOCKET s, int backlog)函数说法不正确的是()

A.listen函数是系统调用

B.listen函数是库函数

C.backlog维护complete connection queue的长度

D.backlog维护incomplete connection queue的长度

答案:BD

答案解析

listen 是在man手册的第2个手册,属于系统调用

backlog维护complete connection queue的长度

28. int listen(SOCKET s, int backlog); 该函数中第二个参数的含义是?()

A.是否打开log信息

B.是否打开后台log信息

C.后台等待连接队列的最大限制值

D.后台等待连接队列的最小限制值

答案:C

答案解析

backlog 为后台等待连接队列的最大限制值

29. 以下关于描述IP地址错误的是()

A.127.*的IP地址用于本机环回(loop back)测试, 通常是127.0.0.1

B.将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号

C.E类IP地址的范围是: 240.0.0.0到247.255.255.255

D.如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号可以和和子网中的其他主机重复

答案:D

答案解析:

A正确:127网段中的地址,都是用于实现本地回环的,常见的 127.0.0.1 地址被用于本地的回环网络测试(也就是自己发自己收,不能对外通信)

B正确:这就是子网掩码的重要功能之一,在网络通信中路由的时候用于判断目标IP属于哪个网络

C正确:了解范围即可

D错误:子网中新增一台主机,则意味着网络号不变(网段号不变),则主机号一定不能重复,否则就无法唯一标识该子网当中的哪台机器,则数据路由的时候就会出问题

30. Internet使用TCP / IP协议实现了全球范围的计算机网络的互连,连接在Internet上的每一台主机都有一个IP地址,下面不能作为互联网上可用的IP地址的是( )

A.201.109.39.68

B.127.0.0.1

C.21.18.33.48

D.120.34.0.18

答案:B

答案解析:

127网段中的地址,用于是实现本地回环,其中 127.0.0.1 地址被用于本地的回环网络测试(也就是自己发自己收,不能对外通信)

31. 【多选题】IP地址是一个4字节的数字,实际上由两部分合成,第一部分是(),第二部分是()

A.网络号

B.主机号

C.网段号

D.以上都不对

答案:AB

答案解析:

IP地址由两部分组成,

  • 一部分是标识自己所属网络的网络号,以便于在网络中寻找指定的子网络,
  • 一部分是自己在该子网络中的主机唯一标识,以便于在该子网络中找到指定的主机

32. IP地址中的主机号有什么作用 ? ()

A.它指定了网络上主机的标识

B.它指定了被寻址的子网中的某个主机

C.它指定了主机所属的网络

D.它指定了设备能够进行通信的网络

答案:B

答案解析:

IP地址由两部分组成:

  • 一部分是标识自己所属网络的网络号,以便于在网络中寻找指定的子网络,
  • 一部分是自己在该子网络中的主机唯一标识,以便于在该子网络中找到指定的主机

A错误:网络上主机的标识,这是IP地址整体的作用

B正确

C错误:这是网络号的功能

D错误:网络的标识都是网络号的功能

33. IPv6地址占()个字节

A.4

B.6

C.8

D.16

答案:D

答案解析:

IPv4版的IP地址是无符号四字节大小,共有接近43亿个IP地址,但是IP地址不够用,因此在IPv6中扩大了IP地址范围为16个字节大小(因为并不向前兼容IPv4所以推广较慢)

34. 下列哪个IP地址可以分配给一台计算机 ? ()

A.256.1.3.4

B.197.3.11.0

C.199.5.89

D.11.15.33.235

答案:D

答案解析:

互联网的网络地址分为A~E五类,其中:

  • A类地址:0.0.0.0 ~127.255.255.255, 主机号是后24位
  • B类地址:128.0.0.0 ~191.255.255.255,主机号是后16位
  • C类地址:192.0.0.0 ~223.255.255.255,主机号是后8位
  • D类地址:224.0.0.0 ~239.255.255.255,后28位为多播组号
  • E类地址:240.0.0.0 ~255.255.255.255,后27位待用

A错误:点分十进制IP地址中,一个数字表示一个字节,256 超过了单字节存储最大值,是一个不符合规则的IP地址

B错误:197是一个C类地址,低8位是主机号,但是197.3.11.0中低八位主机号全为0,而主机号全为0表示一个网段,表示的是一个网络号,主机号全为1的时候,是该子网的广播地址

C错误:参照TCP / IP详解卷一第三章 IP : 网际协议的图3 - 3,代表了一个直接相连的网络。

D正确:作为一个A类地址,是可以分配给一台计算机的。

35. 以下地址中的哪一个和76.32 / 12网段匹配()

A.76.33.214.12

B.76.79.24.11

C.76.58.119.74

D.76.68.204.11

答案:A

答案解析

题干中76.32 / 12 表示网络号占据12个比特位,

  • 子网掩码为 11111111.1111,12个比特位为1, 因此子网掩码十进制表示为 255.240.0.0
  • 76.32使用二进制表示 01001100.00100000, 与子网掩码相与得到网络号,则得到网络号是 01001100.0010 也就是 76.32

A正确.:76.33 与 255.192 相与后得到 76.32,网络号相同

B错误:.76.79 与 255.192 相与后得到 76.64,网络号不同

C错误:.76.58 与 255.192 相与后得到 76.48,网络号不同

D错误:.76.68 与 255.192 相与后得到 76.64,网络号不同

36. 下面哪种设备是组建以太局域网必不可少的?()

A.网桥

B.集线器或交换机

C.路由器

D.中继器

答案:B

答案解析:

A错误:网桥是早期的两端口二层网络设备, 比集线器(Hub)性能更好,但是后来被交换机替代。

B正确:局域网按照传输介质使用的访问控制方法,可以分为以太网、FDDI网和令牌网,目前广泛使用的是以太网,它以集线器或交换机为中心构成。

C错误:路由器的主要功能是路由功能连接其他网络对外通信。我们生活中都是购买路由器组建一个局域网,但是路由器并非必须的设备。

D错误:中继器(RP repeater)是工作在物理层上的连接设备。适用于完全相同的两个网络的互连,主要功能是通过对数据信号的重新发送或者转发,来扩大网络传输的距离

37. 局域网是计算机网络中最流行的一种形式。下面有关局域网的叙述中错误的是()

A.局域网指较小地域范围内的计算机网络,它有多种类型

B.局域网通常为一个单位所拥有,自建自管

C.它主要使用光缆进行连网和数据通信

D.局域网数据传输速率高,延迟时间短,误码率低

答案:C

答案解析:

局域网通常指的是网络覆盖范围在1000米以内的网络,地域范围较小,往往属于一个单位所有,由单位自建自管,具有多种类型。

局域网使用专门铺设的传输介质进行联网和数据通信,数据传输速率高,延迟时间短,误码率低。

故本题选C,一般家庭或企业的局域网布线都是使用普通网线(现在一般网线都是双绞线,当然也有其他的一些种类)

38. 一个广域网和一个局域网相连,且需要进行协议转换,需要的设备是什么。()

A.路由器

B.网关

C.集线器

D.NIC

答案:B

答案解析:

路由器属于网络层设备,IP协议工作在网络层,它是一种负责寻径的网络设备

网关(Gateway)又称网络连接器、协议转换器,是在多个网络之间提供数据转换服务的计算机系统数据转换服务

集线器属于物理层设备

NIC是物理网卡的结构, 是数据链路层, 数据链路层分为LLC和MAC子层

39. 局域网体系结构中 () 被划分成 MAC 和 LLC 两个子层

A.物理层

B.数据链路层

C.网络层

D.运输层

答案:B

答案解析:

  • MAC子层的主要功能包括数据帧的封装 / 卸装,帧的寻址和识别,帧的接收与发送,链路的管理,帧的差错控制等
  • LLC 是在高级数据链路控制(HDLC:High - Level Data - Link Control)的基础上发展起来的

MAC和LLC同属于数据链路层的功能,因此正确选项为:B

40. 局域网中的 MAC层 与 OSI 参考模型()相对应

A.物理层

B.数据链路层

C.网络层

D.传输层

答案:B

答案解析:

OSI参考模型:物理层,数据链路层,网络层,传输层, 会话层, 表示层, 应用层

局域网中的MAC层对应数据链路层。

相关推荐
程序猿编码2 小时前
Linux内核模块实现TCP连接强制断开机制
linux·网络·tcp/ip·内核·内核模块
讨厌下雨的天空2 小时前
进程间通信
linux·服务器
真正的醒悟2 小时前
图解网络9
网络
测试人社区—小叶子2 小时前
Rust会取代C++吗?系统编程语言的新较量
运维·开发语言·网络·c++·人工智能·测试工具·rust
QQ7198725782 小时前
Linux【4】:FTP服务搭建
linux·运维·服务器
习惯就好zz2 小时前
如何解包 Android boot.img 并检查 UART 是否启用
android·linux·dtc·3588·dts·解包·dtb
00后程序员张2 小时前
Python 抓包工具全面解析,从网络监听、协议解析到底层数据流捕获的多层调试方案
开发语言·网络·python·ios·小程序·uni-app·iphone
zl_dfq2 小时前
Linux 之 【进程替换】(execl、execlp、execle、execv、execvp、execve)
linux
乌蒙山连着山外山2 小时前
linux中查询多个匹配字段
java·linux·服务器