18.5 服务器设计
现在我们开始描述一下服务器的设计过程。有两个关键因素影响服务器的设计:
(1) 拨号过程可能会持续15到30秒,所以服务器必须创建一个子进程来处理实际的拨号。
(2) 服务器的精灵进程(父进程)必须管理所有的加锁。
服务器的工作过程如下:
(1) 父进程在服务器的众所周知名字处接收来自客户机的请求。如15.5节所述,这在客户机和服务器之间生成了一个流管道。父进程需要同时处理多个客户机。
(2) 基于客户机要联系的远程系统的名字,父进程查询Systems文件和Devices文件以找到匹配的项。父进程同时也维护一个加锁表,记录哪些设备正在被使用,以避免查询那些已被使用的项。
(3) 如果发现匹配项,父进程会fork一个子进程来进行实际的拨号(这时父进程可以处理其他客户机的请求)。如果拨号成功,子进程会在客户机指定的流管道上将调制解调器的文件描述符传给客户机,并调用exit(0)。如果发生了错误(例如电话线占线、没有响应等),子进程会调用exit(1)。
(4) 子进程结束时,会发送信号SIGCHLD通知父进程。父进程会获取子进程的结束状态(waitpid)。如果子进程成功,父进程就不用再做其他事情。在客户机结束使用调制解调器之前,必须一直对调制解调器加锁。客户机指定的客户机-父进程之间的流管道会一直保持打开状态。这样,当客户机终止时,父进程会得到通知并释放对设备的加锁。如果子进程不成功,父进程会从Systems文件中尝试找到下一个匹配项。如果找到另一个远程系统的匹配项,父进程会返回上一步,创建一个新的子进程来拨号。如果没有找到新的匹配项,父进程会调用send_err后关闭与客户机的流管道。每个客户机都有一个连接,使得子进程在必要时能将调试输出发回给客户机。发生问题时,客户机通常想要看到整个实际拨号过程。
想要更多关于拨号源码的信息吗?你可以查看以下资源:
18.6 服务器源码
服务器包括17个源文件。表18-4详细说明了父进程和子进程所使用的文件。
暂无评论