Qianfeng

DON'T WORRY BE HAPPY
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

unp第五章:客户端和服务端程序

Posted on 2022-03-07 03:39  RonnieOS  阅读(54)  评论(0编辑  收藏  举报
  • 客户端在三次握手收到第二个分节之后,connect就立马返回,但是服务端只有收到最后一个分节才把连接纳入全连接队列。

  • 子进程终止的时候,会给父进程发信号SIGCHILD,但该信号默认被忽略,导致子进程变成僵尸进程。
    这里提一下linux为什么设置僵死态:为了保存子进程的一些执行信息(进程ID,执行cpu时间,返回状态)供父进程在某个时间去拿信息.

信号

信号分为两种

  1. 一个进程发给另一个进程
  2. 内核发给某个进程.
    在子进程终结时,内核负责给父进程发信号.

如果阻塞的系统调用被信号中断了,会产生一个eintr错误.这常常导致accept失败.因此我们在设置信号时,应当设置sa_restart,这使得系统调用得以重新进行.但这不完全保险,最保险的是,当系统调用失败时,查看errno,如果其值为EINTR,那么应该手动重启系统调用.

wait和waitpid

wait和waitpid都是用来回收已终止子进程的.
wait是阻塞的, waitpid除了可以设定wait的进程,还可以增加选项,使得waitpid的调用不阻塞,如果没有已终止子进程,那么waitpid会立即返回.

为什么需要select, poll

客户端回射程序同时面对两个描述符, socket和用户输入, 我们不应让客户端程序阻塞于某个输入上,而是应该阻塞于任一个输入上.

SIGPIPE信号

SIGPIPE信号在写入一个已收到RST的套接字时触发(服务器发FIN,这时写可能会导致RST,再写内核就会发送SIGPIPE信号给进程,默认操作是终止进程)

服务器主机崩溃

如果服务器主机崩溃了,将会发生以下几件事:

  1. 首先服务器主机无法再发送任何网络数据
  2. 客户端在发送数据后会发现收不到ACK,因此会不断重传,大约9分钟.当客户端tcp最终放弃的时候,内核会给客户进程会返回一个错误.
    这个错误是从哪个函数返回的呢?write函数将数据写到内核缓存区就立即返回了,因此网络不可达不会让其返回一个错误.反而是因为阻塞在read的时候,read会返回一个错误.

这个技术仅仅在向服务器发送数据才能检测服务器是否崩溃,但是不发送数据其实也可以检测崩溃,后面会提到SO_KEEPALIVE套接字选项