📄 61.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="54.htm">上一层</a>][<a href="62.htm">下一篇</a>]
<hr><p align="left"><small>发信人: clown (梧桐叶), 信区: UNP <br>
标 题: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月19日18:47:49 星期天), 站内信件 <br>
<br>
本来觉得编写简单的socket应该没有什么问题了,看了本章之后真是感到汗颜。 <br>
1)CHLD信号处理 <br>
在服务器端,对于已经连接的socket,一般都是派生出子进程来进行处理, <br>
这样就要捕捉CHLD信号,否则可能会产生僵尸。一般signal(SIGCHLD, SIG_IGN) <br>
就不会产生僵尸了,注意signal(SIGCHLD, SIG_DFL)会产生僵尸,该信号的SIG_DFL <br>
处理是忽略。 <br>
由于Unix信号是不排队的,也就是说,如果一个信号在阻塞是产生了多次,在 <br>
信号解阻塞以后,只会递交一次。书上有一个使用wait函数(应该使用waitpid)捕 <br>
捉处理CHLD的例子,可以清楚地说明该现象。 <br>
另外,书上提到了一个基本规则:当一个进程阻塞于慢系统调用(slow system <br>
call)时捕捉到一个信号,等到信号处理函数返回时,系统调用可能返回一个EINTR <br>
错误(实际上并不是一个错误)。这样用户就需要对EINTR错误进行特殊的处理,那 <br>
就是按照apue上面介绍的,重新启动被中断的系统调用,这里就是重新调用accept <br>
函数。可惜我在Linux 2.4核心中发现这条规则不成立,为了提高移植性,编程时 <br>
也许应该考虑考虑这条规则。 <br>
2)临界条件 <br>
我以前很少注意到这些临界条件,:(,没想到socket中有这么多潜在的问题: <br>
accept返回前连接夭折,服务器进程终止(可能是服务器父进程,也可能是负责某 <br>
个连接的子进程),服务器崩溃及重启。 <br>
这些临界条件实际就是客户对于服务器的RST响应的处理。对于该问题,书上也 <br>
有一条规则:当一个进程向接收了RST的套接口进行写操作时,内核会给该进程发一 <br>
个SIGPIPE信号,该信号的缺省行为就是终止进程。我查了一下,SIGPIPE是指write <br>
on a pipe with no one to read it。但是我测试时,kill掉负责连接的子进程以后, <br>
再次写时并没有收到SIGPIPE信号。 <br>
3)数据格式 <br>
也就是网络字节序和主机字节序的问题,跨套接口传送结构或者数据时,应该以 <br>
文本方式而不是二进制方式传送,相信大家都知道吧。 <br>
总之,套接字编程中有很多的细节问题,可能是我们以前没有注意到的。 <br>
-- <br>
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.1.61] 发信人: scz ( <br>
小四), 信区: UNP <br>
标 题: Re: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月19日22:53:13 星期天), 站内信件 <br>
<br>
<br>
【 在 clown (梧桐叶) 的大作中提到: 】 <br>
: 3)数据格式 <br>
: 也就是网络字节序和主机字节序的问题,跨套接口传送结构或者数据时,应该以 <br>
~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
<br>
这是RPC机制里XDR的基本功能,也就是corba这些东西的基本功能。 <br>
hton以及ntoh无非是XDR的最简单外在表现。Java的所谓序列化对象就是 <br>
这种意思。对于底层来说,通通是XDR的概念。 <br>
<br>
-- <br>
<br>
也许有一天,他再从海上蓬蓬的雨点中升起, <br>
飞向西来,再形成一道江流,再冲倒两旁的石壁, <br>
再来寻夹岸的桃花。然而,我不敢说来生,也不敢信来生...... <br>
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 211.167.65.123] 发信人: fly <br>
river (飞流直下), 信区: UNP <br>
标 题: Re: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月19日23:05:37 星期天), 站内信件 <br>
<br>
<br>
【 在 clown (梧桐叶) 的大作中提到: 】 <br>
: 本来觉得编写简单的socket应该没有什么问题了,看了本章之后真是感到汗颜。 <br>
: 1)CHLD信号处理 <br>
: 在服务器端,对于已经连接的socket,一般都是派生出子进程来进行处理, <br>
: 这样就要捕捉CHLD信号,否则可能会产生僵尸。一般signal(SIGCHLD, SIG_IGN) <br>
: 就不会产生僵尸了,注意signal(SIGCHLD, SIG_DFL)会产生僵尸,该信号的SIG_DFL <br>
: 处理是忽略。 <br>
: 由于Unix信号是不排队的,也就是说,如果一个信号在阻塞是产生了多次,在 <br>
: 信号解阻塞以后,只会递交一次。书上有一个使用wait函数(应该使用waitpid)捕 <br>
: 捉处理CHLD的例子,可以清楚地说明该现象。 <br>
: 另外,书上提到了一个基本规则:当一个进程阻塞于慢系统调用(slow system <br>
: call)时捕捉到一个信号,等到信号处理函数返回时,系统调用可能返回一个EINTR <br>
: 错误(实际上并不是一个错误)。这样用户就需要对EINTR错误进行特殊的处理,那 <br>
: 就是按照apue上面介绍的,重新启动被中断的系统调用,这里就是重新调用accept <br>
: 函数。可惜我在Linux 2.4核心中发现这条规则不成立,为了提高移植性,编程时 <br>
: 也许应该考虑考虑这条规则。 <br>
: 2)临界条件 <br>
: 我以前很少注意到这些临界条件,:(,没想到socket中有这么多潜在的问题: <br>
: accept返回前连接夭折,服务器进程终止(可能是服务器父进程,也可能是负责某 <br>
: 个连接的子进程),服务器崩溃及重启。 <br>
: 这些临界条件实际就是客户对于服务器的RST响应的处理。对于该问题,书上也 <br>
: 有一条规则:当一个进程向接收了RST的套接口进行写操作时,内核会给该进程发一 <br>
: 个SIGPIPE信号,该信号的缺省行为就是终止进程。我查了一下,SIGPIPE是指write <br>
: on a pipe with no one to read it。但是我测试时,kill掉负责连接的子进程以后, <br>
~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: 再次写时并没有收到SIGPIPE信号。 <br>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
<br>
不应该这样做吧,你把另一端的进程 kill 掉了,他会用 close() 来关掉 <br>
socket 的,于是内核会完成正常的 TCP 关闭过程。 <br>
<br>
应该拔去另一端机器的网线,重启机器,把网线插上去。然后本地进程 <br>
向 socket 写数据时内核就会收到 RST 包了。 <br>
<br>
: 3)数据格式 <br>
: 也就是网络字节序和主机字节序的问题,跨套接口传送结构或者数据时,应该以 <br>
: 文本方式而不是二进制方式传送,相信大家都知道吧。 <br>
: 总之,套接字编程中有很多的细节问题,可能是我们以前没有注意到的。 <br>
<br>
<br>
-- <br>
Nothing but UNIX. <br>
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 166.111.160.6] 发信人: clow <br>
n (梧桐叶), 信区: UNP <br>
标 题: Re: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月20日08:01:50 星期一), 站内信件 <br>
<br>
<br>
【 在 flyriver (飞流直下) 的大作中提到: 】 <br>
: 标 题: Re: unp第五章学习体会 <br>
: 发信站: UNIX编程 (2001年08月19日23:05:37 星期天), 站内信件 <br>
: <br>
: <br>
: <br>
: 【 在 clown (梧桐叶) 的大作中提到: 】 <br>
: : 本来觉得编写简单的socket应该没有什么问题了,看了本章之后真是感到汗颜。 <br>
: : 1)CHLD信号处理 <br>
: : 在服务器端,对于已经连接的socket,一般都是派生出子进程来进行处理, <br>
: : 这样就要捕捉CHLD信号,否则可能会产生僵尸。一般signal(SIGCHLD, SIG_IGN) <br>
: : 就不会产生僵尸了,注意signal(SIGCHLD, SIG_DFL)会产生僵尸,该信号的SIG_DFL <br>
: : 处理是忽略。 <br>
: : 由于Unix信号是不排队的,也就是说,如果一个信号在阻塞是产生了多次,在 <br>
: : 信号解阻塞以后,只会递交一次。书上有一个使用wait函数(应该使用waitpid)捕 <br>
: : 捉处理CHLD的例子,可以清楚地说明该现象。 <br>
: : 另外,书上提到了一个基本规则:当一个进程阻塞于慢系统调用(slow system <br>
: : call)时捕捉到一个信号,等到信号处理函数返回时,系统调用可能返回一个EINTR <br>
: : 错误(实际上并不是一个错误)。这样用户就需要对EINTR错误进行特殊的处理,那 <br>
: : 就是按照apue上面介绍的,重新启动被中断的系统调用,这里就是重新调用accept <br>
: : 函数。可惜我在Linux 2.4核心中发现这条规则不成立,为了提高移植性,编程时 <br>
: : 也许应该考虑考虑这条规则。 <br>
: : 2)临界条件 <br>
: : 我以前很少注意到这些临界条件,:(,没想到socket中有这么多潜在的问题: <br>
: : accept返回前连接夭折,服务器进程终止(可能是服务器父进程,也可能是负责某 <br>
: : 个连接的子进程),服务器崩溃及重启。 <br>
: : 这些临界条件实际就是客户对于服务器的RST响应的处理。对于该问题,书上也 <br>
: : 有一条规则:当一个进程向接收了RST的套接口进行写操作时,内核会给该进程发一 <br>
: : 个SIGPIPE信号,该信号的缺省行为就是终止进程。我查了一下,SIGPIPE是指write <br>
: : on a pipe with no one to read it。但是我测试时,kill掉负责连接的子进程以后, <br>
: ~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: : 再次写时并没有收到SIGPIPE信号。 <br>
: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: <br>
: 不应该这样做吧,你把另一端的进程 kill 掉了,他会用 close() 来关掉 <br>
: socket 的,于是内核会完成正常的 TCP 关闭过程。 <br>
: <br>
: 应该拔去另一端机器的网线,重启机器,把网线插上去。然后本地进程 <br>
: 向 socket 写数据时内核就会收到 RST 包了。 <br>
: <br>
我kill调子进程以后,服务器确实会发送FIN,但是客户没有发送FIN,因此 <br>
连接处于半关闭状态,这时客户是可以发送数据的。但是由于服务器子进程不存在了, <br>
因此会在解收到该客户的数据以后发送RST响应。 <br>
我怀疑对于RST响应,Linux内核作了某些处理,对应用层屏蔽掉了。 <br>
: : 3)数据格式 <br>
: : 也就是网络字节序和主机字节序的问题,跨套接口传送结构或者数据时,应该以 <br>
: : 文本方式而不是二进制方式传送,相信大家都知道吧。 <br>
: : 总之,套接字编程中有很多的细节问题,可能是我们以前没有注意到的。 <br>
: <br>
: <br>
: <br>
: -- <br>
: Nothing but UNIX. <br>
※ 修改:·clown 於 08月20日08:02:53 修改本文·[FROM: 202.114.1.61] <br>
: ※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 166.111.160.6] <br>
发信人: flyriver (飞流直下), 信区: UNP <br>
标 题: Re: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月20日09:09:38 星期一), 站内信件 <br>
<br>
<br>
RST, FIN 都是由内核进行处理的,应用层的进程是接收不到的。 <br>
半关闭应该是 shutdown() 来进行的,close() 是不会进行半关闭的。 <br>
<br>
好久没有看 UNP 了,有些已经忘了。:( <br>
<br>
【 在 clown (梧桐叶) 的大作中提到: 】 <br>
: 【 在 flyriver (飞流直下) 的大作中提到: 】 <br>
: : 标 题: Re: unp第五章学习体会 <br>
: : 发信站: UNIX编程 (2001年08月19日23:05:37 星期天), 站内信件 <br>
: : ~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: : 不应该这样做吧,你把另一端的进程 kill 掉了,他会用 close() 来关掉 <br>
: : socket 的,于是内核会完成正常的 TCP 关闭过程。 <br>
: : 应该拔去另一端机器的网线,重启机器,把网线插上去。然后本地进程 <br>
: : 向 socket 写数据时内核就会收到 RST 包了。 <br>
: 我kill调子进程以后,服务器确实会发送FIN,但是客户没有发送FIN,因此 <br>
: .................(以下省略) <br>
<br>
-- <br>
Nothing but UNIX. <br>
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 166.111.160.6] 发信人: scz <br>
(小四), 信区: UNP <br>
标 题: Re: unp第五章学习体会 <br>
发信站: UNIX编程 (2001年08月20日09:49:55 星期一), 站内信件 <br>
<br>
<br>
【 在 flyriver (飞流直下) 的大作中提到: 】 <br>
: : 个SIGPIPE信号,该信号的缺省行为就是终止进程。我查了一下,SIGPIPE是指write <br>
: : on a pipe with no one to read it。但是我测试时,kill掉负责连接的子进程以后, <br>
: ~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: : 再次写时并没有收到SIGPIPE信号。 <br>
: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <br>
: 不应该这样做吧,你把另一端的进程 kill 掉了,他会用 close() 来关掉 <br>
: socket 的,于是内核会完成正常的 TCP 关闭过程。 <br>
: 应该拔去另一端机器的网线,重启机器,把网线插上去。然后本地进程 <br>
: 向 socket 写数据时内核就会收到 RST 包了。 <br>
<br>
<br>
我也和flyriver一个观点。kill对端进程会导致TCP连接的正常关闭,close() <br>
他的这个拔掉网线的建议还差不多 <br>
<br>
-- <br>
<br>
也许有一天,他再从海上蓬蓬的雨点中升起, <br>
飞向西来,再形成一道江流,再冲倒两旁的石壁, <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -