《UNIX网络编程卷1》读书笔记--第五章TCP客户/服务实例
2017-03-24 11:39
246 查看
前言
本章开始编写一个完整的TCP客户/服务器程序实例。 (1) 客户冲标准输入读入一行文本,并写给服务器 (2)服务器从网络输入读入这行文本,并回射给客户 (3)客户从网络读入这行回射文本,并显示在标准输出上。
(这个图是根据书中原图我重新绘制的图,可以看到服务器调用来了read而客户端调用readline,但是根据之前的讲诉,readline能够保证一次读取“全部”信息,还有书中后面关于str_echo函数的描述,我认为这里TCP服务器应该使用readline更加合理,尽管代码和图中给出的是read调用)
关注点
客户和服务器正常启动防止僵尸进程的信号处理
服务器进程在客户之前终止,客户端情况
服务器主机崩溃,客户端情况
服务器主机崩溃后重启,客户端情况
客户和服务器正常启动与终止
如图所示,正常启动后客户端阻塞于fgets调用,服务器子进程阻塞与readline(read)调用,服务器父进程阻塞于accept调用。因此三个进程都处于睡眠状态。
正常终止:
防止僵尸进程的信号处理
如果父进程没有捕获子进程的SIGCHID信号,那么子进程将成为僵尸进程。
如何捕获?可以采用wait或者waitpid
#include <sys/wait.h> pit_t wait(int *statloc); pid_t waitpid(pid_t pid, in * staloc, int options);
当有父进程fork出多个子进程时,应该采用waitpid获得全部子进程pid来进行信号捕获。调用wait将产生不确定的后果。
遗留问题
服务器进程在客户之前终止,客户端情况
这里说的终止是区别于主机崩溃的终止,也就是说,终止前是有给客户端发送FIN的,服务器主机关机也跟这类终止相同。 但是虽然发送的FIN可以得到客户TCP的ACK回复,但是正阻塞在fgets调用的客户端程序却没有察觉,如果此时客户端输入并且将数据发送给对端,这时服务端会回复RST,为什么?因为这个和一般的终止连接不同,对端进程已经终止,没有进程能识别这个数据。 此时客户调用readline读取到刚开始的FIN,这时readline返回0,报告连接终止。 连接已经终止,但是如果我们此时没有终止进程,这时可能的,我们再继续往不存在的连接发送数据就会产生SIGPIPE信号(内核向应用进程发送),该信号的默认行为是终止进程,因此进程必须捕获它以免不情愿地被终止。
服务器主机崩溃,客户端情况
服务器主机崩溃,那么用户发送的数据将使得路由器相应一个destination unreachable的ICMP消息。客户端将会产生数次重传。处理这种问题可以有两种方法: 1.对readline调用设置一个更短的超时 2.采用SO_KEEPALIVE选项
服务器主机崩溃后重启,客户端情况
服务器重启后,它的TCP丢失了崩溃前的所有连接消息,因此服务器TCP对于所有收到的来自客户的数据分节响应一个RST。而此时客户正阻塞在readline调用,导致该调用返回ECONNRESET
相关文章推荐
- 用VB实现客户——服务器(TCP/IP)编程实例
- WCF 第五章 并发和实例(服务行为)
- UNIX网络编程卷一:第五章 TCP客户/服务器程序实例
- 第五章 TCP回射客户程序
- TCP多进程并发编程-回射服务/客户程序
- unix网络编程各种TCP客户-服务器程序设计实例(三)
- unix网络编程各种TCP客户-服务器程序设计实例(四)
- unix网络编程各种TCP客户-服务器程序设计实例(三)
- linux c学习笔记----TCP基础客户/服务编程(socket,bind等)
- WCF 第五章 并发和实例(服务行为)
- 简单的TCP回射服务程序与客户程序(修改自UNP一书)
- 简单进程池实现多TCP客户服务
- VC++ TCP/IP 服务/客户程序源代码
- unix网络编程各种TCP客户-服务器程序设计实例(二)
- VC++ TCP/IP 服务/客户程序源代码
- UNIX网络编程学习(11)--分析TCP回射服务+客户程序:正常启动与正常终止
- unix网络编程各种TCP客户-服务器程序设计实例附环境搭建和编译方法(一)
- linux c学习笔记----TCP基础客户/服务编程(socket,bind等)
- Linux网络编程(1):TCP客户服务程序设计
- 读书笔记之 简单时间获取客户/服务程序