网络编程常见面试题

一、TCP协议的概念和特点

  TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。特点:

  • 面向连接:通过三次握手建立连接,四次挥手断开连接;
  • 可靠传输:确认应答机制、超时重传、拥塞控制;
  • 面向字节流:
  1. 确认应答机制:TCP将每个字节的数据都进行了编号,即为序列号。每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

  2. 超时重传:主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B; 如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发;主机A未收到B发来的确认应答,也可能是因为ACK丢失了,因此主机B会收到很多重复数据.。那么TCP协议需要能够识别出那些包是重复的包,,并且把重复的丢弃掉.,这时候我们可以利用序列号, 就可以很容易做到去重的效果。

  3. 拥塞控制:每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口。
    拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案

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

二、UDP协议的概念和特点

  UDP(User Data Protocol,用户数据报协议)是一个简单的面向数据报的运输层协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地。由于UDP在传输数据报前不用再客户和服务器之间建立一个连接,且没有超时重发等机制,所以传输速度很快。特点:

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

三、TCP协议和UDP协议的区别

  1、TCP面向连接,UDP是无连接;
  2、TCP提供可靠的服务,UDP尽最大努力交付,即不保证可靠交付;
  3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流,UDP是面向报文的;
  4、TCP保证数据顺序,UDP不保证;
  5、TCP首部开销20字节,UDP的首部开销小,只有8个字节;
  6、UDP传输速度更快,对系统资源需求更少;

四、TCP三次握手和四次挥手的过程

1、三次握手

2、四次挥手

3、CLOSE-WAIT状态

   在被动关闭连接情况下,在已经接收到FIN,但是还没有发送相应的ACK的时刻,连接处于CLOSE_WAIT状态。通常来讲,CLOSE_WAIT状态的持续时间应该很短,正如SYN_RCVD状态。

现象:SOCKET出现大量处于CLOSE_WAIT状态。

原因:主要原因是某种情况下对方关闭了socket链接,但是本方没有关闭相应连接(可能正在从此链路读取或者写数据,收到TCP返回的SOCKET_ERROR未做关闭操作)。

解决措施:一般情况下是应用层代码编写问题。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不是AGAIN,就断开连接。

4、TIME-WAIT状态

  由上面的TCP状态图可知,首先调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time-wait状态,也就是说该发送方会保持2MSL事件之后才会回到初始状态,MSL值是数据包在网络中的最大生存时间。

现象:SOCKET出现大量处于TIME_WAIT状态,严重情况下无法创建SOCKET

原因:发起主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2MSL,在Windows下默认为4分钟,不同的操作系统,默认时间不相同。TIME_WAIT状态下的socket不能被回收使用。具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。

解决SOCKET耗尽措施:修改系统关于TIME_WAIT相关的参数。《1》修改TIME_WAIT等待的时间。《2》允许将TIME-WAIT sockets重新用于新的TCP连接。设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。《3》开启TCP连接中TIME-WAIT sockets的快速回收。

为什么要这样做而不是直接进入CLOSED状态?原因有二:1)保证TCP协议的全双工连接能够可靠关闭;2)保证这次连接的重复数据段从网络中消失;

五、Select模型

过程:

(1)从用户空间拷贝fd_set到内核空间;

(2)遍历所有fd,调用全部指定设备的poll函数,将当前进程加入到各个设备的等待列表中;

(3)当设备就绪时,将唤醒等待队列中的所有节点,当前进程获取到完成信号,select/poll将返回。

(4)如果设备未就绪,则让出CPU进入阻塞状态,timeout之后将再次进行上述操作。

select的缺点:

(1)最大并发数有限制。支持的文件描述符数量太少,默认是32* 32 = 1024,可修改;

(2)效率低。每次都会线性扫描整个fd_set,集合越大速度越慢;fd_set内核/用户空间内存拷贝问题。

六、epoll模型

(1)调用epoll_create

在虚拟的epoll文件系统里创建一个file结点。在内核里,一切皆文件。所以,epoll向内核注册了一个文件系统,用于存储上述的被监控socket,当然这个file不是普通文件,它只服务于epoll。

在内核cache里创建一个红黑树用于存储需要监听的socket,以支持快速的查找、插入、删除。epoll在被内核初始化时(操作系统启动),同时会开辟出epoll自己的内核高速cache区,用于安置每一个我们想监控的socket。

建立一个list链表,用于存储准备就绪的事件

(2)调用epoll_ctl

socket放到epoll文件系统里file对象对应的红黑树上

给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪list链表里。所以,当一个socket上有数据到了,内核在把网卡上的数据copy到内核中后就来把socket插入到准备就绪链表里了。

(3)调用epoll_wait

观察list链表里有没有数据。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。而且,通常情况下即使我们要监控百万计的句柄,大多一次也只返回很少量的准备就绪句柄而已,所以,epoll_wait仅需要从内核态copy少量的句柄到用户态而已。

总结:

一颗红黑树,一张准备就绪句柄链表,少量的内核cache,解决了大并发下的socket处理问题。执行epoll_create时,创建了红黑树和就绪链表; 执行epoll_ctl时,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树干上,然后向内核注册回调函数,用于当中断事件来临时向准备就绪链表中插入数据; 执行epoll_wait时立刻返回准备就绪链表里的数据即可。

两种触发模式的区别:

LT(Level Triggered水平触发)模式下,只要一个句柄上的事件一次没有处理完,会在以后调用epoll_wait时重复返回这个句柄,而ET(Edge Triggered 边沿触发)模式仅在第一次返回。水平触发同时支持block和no-block socket,边沿触发只支持no-block socket。默认为LT,可以在epoll_ctl注册事件是指定为ET。

两种模式的实现:

当一个socket句柄上有事件时,内核会把该句柄插入上面所说的准备就绪list链表,这时我们调用epoll_wait,会把准备就绪的socket拷贝到用户态内存,然后清空准备就绪list链表,最后,epoll_wait检查这些socket,如果是LT模式,并且这些socket上确实有未处理的事件时,又把该句柄放回到刚刚清空的准备就绪链表。所以,LT模式的句柄,只要它上面还有事件,epoll_wait每次都会返回。

两种模式的优缺点:

         LT优点:当进行socket通信的时候,保证了数据的完整输出,进行IO操作的时候,如果还有数据,就会一直的通知。缺点:由于只要还有数据,内核就会不停的从内核空间转到用户空间,所有占用了大量内核资源,试想一下当有大量数据到来的时候,每次读取一个字节,这样就会不停的进行切换。内核资源的浪费严重。效率来讲也是很低的。

         ET优点:每次内核只会通知一次,大大减少了内核资源的浪费,提高效率。缺点:不能保证数据的完整。不能及时的取出所有的数据。

          LT:稳定可靠但效率低;ET:不可靠,使用复杂但效率高;

 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值