[八股] Linux网络编程八股
点个小赞关注一波,持续更新……
[专栏]嵌入式软件校招笔记(点击跳转)
请说一下socket网络编程中客户端和服务端用到哪些函数?(经常问到)
socket()
:创建一个socket。bind()
:绑定IP地址、端口等信息到socket上。listen()
:设置允许的最大连接数。accept()
:接收客户端上来的连接。send()
和recv()
或者read()
和write()
:用于收发数据。socket()
:创建一个socket。connect()
:连接到服务器的socket。send()
和recv()
或者read()
和write()
:用于收发数据。
在Socket网络编程中,客户端和服务端主要使用以下函数:
服务端:
客户端:
补充:在多线程网络编程中还经常用到端口复用,在Linux系统中,可以通过
setsockopt
函数来设置端口复用;端口复用目的:防止服务器重启时之前绑定的端口还未释放:当服务器需要重启时,经常会碰到端口尚未完全关闭的情况,这时如果不设置端口复用,则无法完成绑定,因为端口还处于被别的套接口绑定的状态之中。
说一下同步与异步的区别,阻塞与非阻塞的区别?
同步与异步,阻塞与非阻塞是计算机科学中的重要概念,它们主要描述的是程序在执行过程中的行为模式。
同步与异步:
- 同步:执行一个操作时,在没有得到结果之前,该调用就不返回或继续执行后续操作。简单来说,同步就是必须一件一件事做,等前一件做完了才能做下一件事。
- 异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出之后,被调用者通过“状态”、“通知”、“回调”三种途径通知调用者。
阻塞与非阻塞:
- 阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
- 非阻塞:进程给CPU传达任务后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程3。
总结来说,同步和异步关注的是消息通知的机制,而阻塞和非阻塞关注的是程序在等待消息通知时的状态。
请介绍一下5种IO模型
在计算机网络编程中,有5种常见的I/O模型:
- 阻塞I/O:在发起一个I/O操作后,进程会被挂起,直到数据准备就绪并且已经从内核空间拷贝到用户空间后,进程才会被唤醒1。
- 非阻塞I/O:在发起一个I/O操作后,如果数据还没有准备好,操作会立即返回一个错误码,进程可以继续执行其他任务。进程需要不断地轮询去检查数据是否已经准备就绪1。
- I/O复用:通过select、poll、epoll等函数,一个进程可以同时监控多个文件描述符。当任何一个文件描述符准备就绪时,函数返回,然后进程可以进行读写操作。这种模型可以让单个进程高效地处理多个并发连接1。
- 信号驱动I/O:进程使用sigaction系统调用启动一个信号处理函数,然后返回进行其他工作。当数据准备就绪时,进程会收到一个SIGIO信号,可以在信号处理函数中调用recvfrom来读取数据1。
- 异步I/O:异步I/O是唯一一种真正的异步模型。进程发起一个I/O操作后立即返回进行其他工作,当数据准备就绪并且已经拷贝到用户空间后,进程会收到一个信号,通知其I/O操作已经完成。
参考回答
- 阻塞IO:调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
- 非阻塞IO:非阻塞等待,每隔一段时间就去检查IO事件是否就绪。没有就绪就可以做其他事情。
- 信号驱动IO:Linux用套接口进行信号驱动IO,安装一个信号处理函数,进程继续运行并不阻塞,当IO事件就绪,进程收到SIGIO信号,然后处理IO事件。
- IO多路复用:Linux用select/poll函数实现IO复用模型,这两个函数也会使进程阻塞,但是和阻塞IO所不同的是这两个函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检查。知道有数据可读或可写时,才真正调用IO操作函数。
- 异步IO:Linux中,可以调用aio_read函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。用户可以直接去使用数据。
答案解析
前四种模型--阻塞IO、非阻塞IO、多路复用IO和信号驱动IO都属于同步模式,因为其中真正的IO操作(函数)都将会阻塞进程,只有异步IO模型真正实现了IO操作的异步性。
异步和同步的区别就在于,异步是内核将数据拷贝到用户区,不需要用户再自己接收数据,直接使用就可以了,而同步是内核通知用户数据到了,然后用户自己调用相应函数去接收数据。
讲下IO多路复用
最基础的 TCP 的 Socket 编程,它是阻塞 I/O 模型,基本上只能一对一通信,那为了服务更多的客户端,我们需要改进网络 I/O 模型。
比较传统的方式是使用多进程/线程模型,每来一个客户端连接,就分配一个进程/线程,然后后续的读写都在对应的进程/线程,这种方式处理 100 个客户端没问题,但是当客户端增大到 10000 个时,10000 个进程/线程的调度、上下文切换以及它们占用的内存,都会成为瓶颈。
为了解决上面这个问题,就出现了 I/O 的多路复用,。。比较常用的有
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
记录本人校招过程中遇到的问题及笔记整理!后续会持续更新