《UNIX网络编程 卷1:套接字联网API(第3版)》——8.9 服务器进程未运行

简介: 我们下一个要检查的情形是在不启动服务器的前提下启动客户。如果我们这么做后在客户上键入一行文本,那么什么也不发生。客户永远阻塞于它的recvfrom调用,等待一个永不出现的服务器应答。然而这是一个很好的例子,它要求我们更多地了解底层协议以理解网络应用进程将发生什么。

本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第8章,第8.9节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”公众号查看

8.9 服务器进程未运行

我们下一个要检查的情形是在不启动服务器的前提下启动客户。如果我们这么做后在客户上键入一行文本,那么什么也不发生。客户永远阻塞于它的recvfrom调用,等待一个永不出现的服务器应答。然而这是一个很好的例子,它要求我们更多地了解底层协议以理解网络应用进程将发生什么。

首先,我们在主机macosx上启动tcpdump,然后在同一个主机上启动客户,指定主机freebsd4为服务器主机。接着,我们键入一行文本,不过这行文本没有被回射。

macosx % udpcli01 172.24.37.94
hello, world            我们键入这一行
                    但没有任何内容回射回来

图8-10给出了tcpdump的输出。

screenshot

首先我们注意到,在客户主机能够往服务器主机发送那个UDP数据报之前,需要一次ARP请求和应答的交换。(我们把这个交换保留在tcpdump的输出中,是为了强调在IP数据报可发往本地网络上另一个主机或路由器之前,还是有可能出现ARP请求-应答的。)

我们从第3行看到客户数据报发出,然而从第4行看到,服务器主机响应的是一个"port unreach-able"(端口不可达)ICMP消息。(长度13是12个字符加换行符。)不过这个ICMP错误不返回给客户进程,其原因我们稍后讲述。客户永远阻塞于图8-8中的recvfrom调用。我们还指出ICMPv6也有端口不可达错误类型,类似于ICMPv4(见图A-15和图A-16),因此这里讨论的结果对于IPv6也类似。

我们称这个ICMP错误为异步错误(asynchronous error)。该错误由sendto引起,但是sendto本身却成功返回。回顾2.11节,我们知道从UDP输出操作成功返回仅仅表示在接口输出队列中具有存放所形成IP数据报的空间。该ICMP错误直到后来才返回(图8-10所示为4ms之后),这就是称其为异步的原因。

一个基本规则是:对于一个UDP套接字,由它引发的异步错误却并不返回给它,除非它已连接。我们将在8.11节讨论如何给UDP套接字调用connect。很少有人明白套接字最初实现时为什么做此设计决策。(实现内涵在TCPv2第748~749页讨论。)

考虑在单个UDP套接字上接连发送3个数据报给3个不同的服务器(即3个不同的IP地址)的一个UDP客户。该客户随后进入一个调用recvfrom读取应答的循环。其中有2个数据报被正确递送(也就是说,3个主机中有2个在运行服务器),但是第三个主机没有运行服务器。第三个主机于是以一个ICMP端口不可达错误响应。这个ICMP出错消息包含引起错误的数据报的IP首部和UDP首部。(ICMPv4和ICMPv6出错消息总是包含IP首部和所有的UDP首部或部分TCP首部,以便其接收者确定由哪个套接字引发该错误,如图28-21和图28-22所示。)发送这3个数据报的客户需要知道引发该错误的数据报的目的地址以区分究竟是哪一个数据报引发了错误。但是内核如何把该信息返回给客户进程呢?recvfrom可以返回的信息仅有errno值,它没有办法返回出错数据报的目的IP地址和目的UDP端口号。因此做出决定:仅在进程已将其UDP套接字连接到恰恰一个对端后,这些异步错误才返回给进程。

只要SO_BSDCOMPAT套接字选项没有开启,Linux甚至对未连接的套接字也返回大多数ICMP“destination unreachable”(目的地不可达)错误。图A-15中除代码为0、1、4、5、11和12之外的所有ICMP目的地不可达错误均被返回。

我们将在28.7节再次讨论UDP套接字上异步错误的这个问题,并给出一个使用我们自己的守护进程获取未连接套接字上这些错误的简便方法。

相关文章
|
13天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
1月前
|
域名解析 关系型数据库 MySQL
怎样用自己电脑搭建网络服务器!不花一分钱
怎样用自己电脑搭建网络服务器!不花一分钱
51 1
|
2月前
计算机网络:思科实验【1-访问WEB服务器】
计算机网络:思科实验【1-访问WEB服务器】
计算机网络:思科实验【1-访问WEB服务器】
|
2月前
|
安全 Apache
Metasploit -- 对Apache HTTP服务器守护进程中断复现
Metasploit -- 对Apache HTTP服务器守护进程中断复现
20 0
|
1月前
|
Linux Shell 网络安全
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
【Shell 命令集合 网络通讯 】Linux 与SMB服务器进行交互 smbclient命令 使用指南
46 1
|
1月前
|
Linux 网络安全 Python
如何在服务器上运行python文件
如何在服务器上运行python文件
|
4天前
|
存储 监控 安全
什么情况下物理服务器会运行出错?
物理服务器,也称为裸机服务器,一般可以提供高性能计算水平和巨大的存储容量。然而,它们也难免会遇到一些问题。运行出错时,可能会导致停机和数据丢失。
28 15
|
16天前
|
Python
Python网络编程基础(Socket编程)UDP服务器编程
【4月更文挑战第8天】Python UDP服务器编程使用socket库创建UDP套接字,绑定到特定地址(如localhost:8000),通过`recvfrom`接收客户端数据报,显示数据长度、地址和内容。无连接的UDP协议使得服务器无法主动发送数据,通常需应用层实现请求-响应机制。当完成时,用`close`关闭套接字。
|
1月前
|
Shell Linux 网络安全
【Shell 命令集合 网络通讯 】Linux 管理Apache HTTP服务器 httpd命令 使用指南
【Shell 命令集合 网络通讯 】Linux 管理Apache HTTP服务器 httpd命令 使用指南
30 0
|
1月前
|
Shell Linux Apache
【Shell 命令集合 网络通讯 】Linux 管理Apache HTTP服务器 apachectl命令 使用教程
【Shell 命令集合 网络通讯 】Linux 管理Apache HTTP服务器 apachectl命令 使用教程
162 1

热门文章

最新文章