了解一些边界条件,通过观察这些情形,弄清在网络层次发生什么以及它们怎样反映到套接字api,这将很多其它地理解这些层次的工作原理,体会怎样编写应用程序来处理这些情形。

//--------------------------------1.刚连接立即断开----------------------------------

当三TCP路握手完毕从而连接建立之后。客户TCP却发送了RST,在server端看来,就在该连接已由TCP排队,等着server进程调用accept的时候RST到达。

怎样处理这样的中止的连接依赖于不同的实现,源自Berkley的实现全然在内核中处理中止的连接,server进程根本看不到。大多数SVR4实现则返回一个错误给server进程。作为accept的返回结果。

//--------------------------------2.server进程终止----------------------------------

验证一切正常后,找到server子进程的进程id,运行kill杀死子进程id,作为进程终止处理的部分工作,子进程中全部打开着的描写叙述符都被关闭,这就导致向客户发送一个FIN。而客户TCP则响应以一个ACK,这就是TCP连接终止的工作的前半部分。

而客户堵塞在fgets调用上。等待从终端接收一行文本。于是键入另外一行文本,客户TCP接着把数据发送给server。TCP同意这么做。由于客户TCP接收到FIN仅仅是表示server进程已经关闭了连接的server端,从而进程不再往当中发送不论什么数据而已(而非并不是告知客户TCPserver进程已经终止)。

当serverTCP接收到来自客户的数据时,既然先前打开那个套接字的进程已经终止。于是响应一个RST(可通过tcpdump命令验证)。

接着的情况分为2种,得看时序了

1.由于客户在刚刚调用writen后。马上调用readline,而且由于之前TCP接收到的FIN(RST还没到),所以readline马上返回0。即受到未预期的EOF,于是以出错信息(server terminated prematurely。服务器过早终止)。

2.假设readline发生在收到RST之后,这时候客户既收到了FIN,又收到了RST,则readline返回一个ECONNRESET,即connection rest by peer,对方复位连接的错误。

//--------------------------------------3.SIGPIPE-------------------------------------------

当进程向某个已收到RST的套接字运行写操作时,内核该进程发送一个SIGPIPE信号,该信号的默认行为是终止进程,因此进程必须捕获它以免不情愿地被终止,但不管该进程是捕获该信号并从其信号处理函数返回还是简单忽略该信号,写操作都将返回EPIPE错误。

第一次写操作引发收到RST。第二次引发SIGPIPE信号,写一个已经接收到FIN的套接字不成问题,可是写一个已经接收到RST的套接字则是个错误。

假设SIGPIPE信号出现时须要採取特殊措施,可能须要在日志文件里登记,那么就必须捕获该信号。

//------------------------------------4.server主机崩溃---------------------------------------

当server和client确认正常后,然后从网络上断开server主机。并在客户键入另外一行文本,这样也模拟了当客户发送数据时server主机不可达的情形,即建立连接后某些中间路由器不工作的情形。

客户writen后,随后堵塞于readline的调用,假设用tcpdump观察网络就会发现,客户TCP持续重传数据分节,试图从server上接收一个ACK。

源自Berkley的实现重传该数据分节12次,共等待约9分钟才放弃重传。当客户TCP最后最终放弃时,给客户进程返回一个错误。

既然客户堵塞在readline函数调用上。那么该调用将返回一个错误。假设server追已崩溃,从而对客户的数据分节根本没有响应,那么所返回的错误时是ETIMEDOUT,然后假设某个中间路由器判定server主机已不可达。从而响应一个destination
unreachable的ICMP消息,那么所返回的错误是EHOSTUNREACH或ENETUNREACH。

虽然我们客户终于还是能够发现对端主机已经崩溃或者不可达。只是有时候我们须要比不得不等待9分钟更快地检測出这样的情况。所用的方法就是对readline调用设置一个超时。

//------------------------------------5.server崩溃后重新启动----------------------------------------

如上的情况下,假设在server主机崩溃时客户不主动给server发送数据,那么客户将不会知道服务里主机已经崩溃(没使用KEEP_ALIVE套接字心跳包选项)。

连接建立正常后。server主机崩溃并重新启动,接着在客户上键入一行文本,它将作为一个TCP数据分节发送到server主机。

当server主机崩溃后重新启动时。它的TCP丢失了崩溃前的全部连接信息,因此serverTCP对于所收到的来自客户的数据分节响应以一个RST,当客户TCP收到该RST时,客户正堵塞于readline调用。导致该调用返回ECONNRESET错误。

//----------------------------------6.server主机关机----------------------------------------

当server进程正在执行时,server主机被操作员关机时将会发生什么呢。Unix 系统关机时,init进程通常先给全部进程发送SIGTERM信号(该信号可被捕获),等待一段固定时间(往往是5~20秒之间),然后给全部仍在执行的进程发送SIGKILL信号(该信号不能被捕获)。这么做留给全部执行的进程一小段的时间来清除和终止。假设我们不捕获SIGTERM信号并终止,我们的server将由SIGKILL信号终止。接下来和第2条一样了。

apue和unp的学习之旅07——多种边界条件的讨论的更多相关文章

  1. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  2. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  3. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  4. WCF学习之旅—第三个示例之三(二十九)

    上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...

  5. WCF学习之旅—WCF服务部署到IIS7.5(九)

    上接   WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...

  6. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  7. WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...

  8. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  9. WCF学习之旅—WCF服务的批量寄宿(十三)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...

随机推荐

  1. head---显示文件的开头的内容

    head命令用于显示文件的开头的内容.在默认情况下,head命令显示文件的头10行内容. 语法 head(选项)(参数) 选项 -n<数字>:指定显示头部内容的行数: -c<字符数& ...

  2. [APIO2010]巡逻(树的直径)

    [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到 ...

  3. HNU 12876 Quite Good Numbers 完美数变形

    筛法是一种很快的方法,贴代码纪念一下. 做法很像筛法 #include <iostream> #include <cstdio> #include <cstring> ...

  4. Unity调用Android的两种方式:其一、调用jar包

    unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...

  5. C# 从需要登录的网站上抓取数据

    [转] C# 从需要登录的网站上抓取数据 背景:昨天一个学金融的同学让我帮她从一个网站上抓取数据,然后导出到excel,粗略看了下有1000+条记录,人工统计的话确实不可能.虽说不会,但作为一个学计算 ...

  6. Varnish 缓存加速, Varnish 菜鸟看过来,Varnish实战

    Varnish可以有效降低web服务器的负载,提升访问速度.按照HTTP协议的处理过程,web服务器接受请求并且返回处理结果,理想情况下服务器要在不做额外处理的情况下,立即返回结果,但实际情况并非如此 ...

  7. JSTL标准标签库具体解释

    JSTL标签库的使用是为类弥补html表的不足.规范自己定义标签的使用而诞生的. 在告别modle1模式开发应用程序后.人们開始注重软件的分层设计,不希望在jsp页面中出现java逻辑代码,同一时候也 ...

  8. 会变得ActionBar,让你的ActionBar与众不同

    话不多说先看两张图: github地址:https://github.com/Smalinuxer/android-SlideActionBar 原理什么的有时间再讲,或者自行看代码; 兴许还会补充新 ...

  9. ubuntu下安装RemixOS双系统(Android x86)

    这篇文章主要讲在怎样在ubuntu下安装RemixOS pc版(Android x86版本号),下面两种做法的思路都适合安装不论什么版本号的Android x86版本号到ubuntu系统上,仅仅须要改 ...

  10. 【HDU 5402】Travelling Salesman Problem(构造)

    被某题卡SB了,结果这题也没读好...以为每一个格子能够有负数就当搜索做了.怎么想也搜只是去,后来发现每一个格子是非负数,那么肯定就是构造题. 题解例如以下: 首先假设nn为奇数或者mm为奇数,那么显 ...