网络编程(四)
多进程服务端
并发服务器端的实现方法
- 多进程服务器:通过创建多个进程提供服务。
- 多路复用服务器:通过捆绑并统一管理I/O对象提供服务。
- 多线程服务器:通过生成与客户端等量的线程提供服务。
fork函数创建进程
1 |
|
fork函数将创建调用的进程副本。并非根据完全不同的程序创建进程,而是复制正在运行的、调用fork函数的进程。两个进程都将执行fork函数调用后的语句。因为通过同一个进程、复制相同的内存空间,之后的程序流要根据fork函数的返回值加以区分。
- 父进程:fork函数返回子进程ID。
- 子进程:fork函数返回0。
僵尸进程及产生原因
进程在执行完main函数中的程序后应该被销毁,但有时这些进程变成僵尸进程,占用系统中的重要资源。这种状态下的进程被称作“僵尸进程”。
调用fork函数产生子进程的终止方式:
- 传递参数并调用exit函数。
- main函数中执行return语句并返回值。
向exit函数传递的参数值和main函数的return语句返回的值都会传递给操作系统。而操作系统不会销毁子进程,直到把这些值传递给产生该子进程的父进程。处在这种状态下的进程就是僵尸进程。将子进程变成僵尸进程的正是操作系统。
如果父进程未主动要求获得子进程的结束状态值,操作系统将一直保存,并让子进程长时间处于僵尸进程状态。
销毁僵尸进程
wait函数
为了销毁子进程,父进程应主动请求获取子进程的返回值。
1 |
|
调用wait函数时,如果没有已终止的子进程,那么程序将阻塞直到有子进程终止,需要谨慎使用。
waitpid函数
为了防止阻塞,可以使用waitpid函数。
1 |
|
信号与signal函数
1 |
|
第一个参数signo
为特殊信息,第二个参数void (*func)(int)
为无特殊情况下将要调用的函数指针。
可以在signal函数中注册的部分特殊情况:
- SIGALRM:已通过调用alarm函数注册的时间。
- SIGINT:输入CTRL+C。
- SIGCHLD:子进程终止。
1 |
|
利用sigaction函数进行信号处理
1 |
|
基于进程的并发服务器模型
每当有客户端请求服务时,回声服务器端都创建子进程以提供服务。
与之前的回声服务器端的区别所在:
第一阶段:回声服务器端(父进程)调用accept函数受理连接请求。
第二阶段:此时获取的套接字文件描述符创建并传递给子进程。
第三阶段:子进程利用传递来的文件描述符提供服务。
通过管道实现进程间通信
为了完成进程间通信,需要创建管道。管道并非属于进程的资源,而是和套接字一样,属于套作系统。所以,两个进程通过操作系统提供的内存空间进行通信。
1 |
|
对于使用单个管道实现互相通信需要注意进程间的收发消息顺序,对于进管道的数据,先使用read函数的进程会先获得数据。为了避免这种不确定性,可以创建两个管道,各自负责不同的数据流动。
I/O复用
select函数的功能和调用顺序
使用select函数时可以将多个文件描述符集中到一起统一监视。
- 是否存在套接字接收数据?
- 无需阻塞传输数据的套接字有哪些?
- 那些套接字发生了异常?
select函数的调用方法和顺序如下:
设置文件描述符
监视文件描述符可以视为监视套接字。首先需要将要监视的文件描述符集中到一起,同时按照监视项进行区分。使用fd_set数组变量执行此操作。该数组是存有0和1的位数组。如果该为设置为1,则表示该文件描述符是监视对象。
由于fd_set以位为操作,直接操作会繁琐,所以在库中定义了几个宏:
- FD_ZERO(fd_set* fdset); 将fd_set变量的所有位初始化为0。
- FD_SET(int fd, fd_set* fdset); 在参数fdset指向的变量中注册文件描述符fd的信息。
- FD_CLR(int fd, fd_set* fdset); 在参数fdset指向的变量中清除文件描述符fd的信息。
- FD_ISSET(int fd, fd_set* fdset); 若参数fdset指向的变量中包含文件描述符fd的信息,则返回“真”。
设置检查(监视)范围及超时
1 |
|
多播与广播
多播方式的数据传输是基于UDP完成的。采用多播时,可以同时向多个主机传递数据。
广播只能向同一网络中的主机传输数据。
多播的数据传输方式及流量方面的优点
优点如下:
- 多播服务器端针对特定多播组,只发送1次数据。
- 即使只发送1次数据,但该组内的所有客户端都会接收到数据。
- 多播组数可在IP地址范围内任意增加。
- 加入特定组即可接受发往该多播组的数据。
多播组是D类IP地址(224.0.0.0 ~ 239.255.255.255)。
广播的理解及实现方法
广播也是基于UPD完成的。根据传输数据时使用的IP地址的形式,分为以下两种:
- 直接广播。
- 本地广播。
直接广播的IP地址除了网络中的地址外,其余主机地址全部设置为1。例如,希望向网络地址192.12.34中的所有主机传输数据时,可以向192.12.34.255传输。
本地广播中使用的IP地址限定为255.255.255.255。例如,192.32.24网络中的主机向255.255.255.255传输数据时,数据将传输到192.32.24网络中的所有主机。