
UNIX网络编程卷一(第三版)
文章平均质量分 91
吃着火锅x唱着歌
这个作者很懒,什么都没留下…
展开
-
UNIX网络编程卷一 学习笔记 第二十四章 带外数据
许多传输层都有带外数据(out-of-band data)的概念,它有时也称为经加速数据(expedited data)。其想法是一个连接的某端发生了重要的事情,且该端希望迅速通告其对端,这里的迅速指这种通知应该在已经排队等待发送的任何普通(有时也称带内)数据前发送,即带外数据被认为比普通数据优先级更高。带外数据并不要求在客户和服务器间再使用一个连接,而是映射到已有的连接中。但几乎每个传输层都各自有不同的带外数据实现,而UDP作为一个极端的例子,没有实现带外数据。本章我们只关注TCP的带外数据模型,并描述原创 2023-07-19 22:45:57 · 299 阅读 · 1 评论 -
UNIX网络编程卷一 学习笔记 第三十一章 流
TPI是一个基于消息的接口,它定义了在应用进程(如XTI函数库或套接字函数库)和传输层之间沿着流上行和下行交换的消息,包括消息的格式和每个消息执行的操作。getmsg函数的最后一个参数是一个值-结果参数,如果调用时指定的flagsp参数指向的整数值为0,则返回的是流中第一个消息(既可能是普通消息,也可能是高优先级消息),如果该整数值为RS_HIPRI,那就等待一个高优先级消息到达流头,无论哪种情况,存放到flagsp参数指向的整数中的值根据所返回消息的类型或为0,或为RS_HIPRI。原创 2023-09-06 23:29:13 · 613 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第三十章 客户/服务器程序设计范式
开发一个Unix服务器程序时,我们本书做过的进程控制:1.迭代服务器(iterative server),它的适用情形极为有限,因为这样的服务器在完成对当前客户的服务前无法处理已等待服务的新客户。2.并发服务器(concurrent server),为每个客户调用fork派生一个子进程。传统上大多Unix服务器程序属于这种类型。3.使用select函数处理多个客户的单个TCP服务器进程。4.并发服务器的修改,为每个客户创建一个线程,取代一个进程。我们本章探究并发服务器的另两类变体:1.预先派生子原创 2023-09-04 01:16:31 · 983 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十九章 数据链路访问
创建PF_PACKET套接字时,调用socket的第二个参数既可以是SOCK_DGRAM,表示扣除链路层首部的帧,也可以是SOCK_RAW,表示完整的链路层帧。大多应用进程只需要分组首部而不需要分组数据,这个技术减少了由BPF复制到应用进程的数据量,例如,tcpdump默认把该值设置为96字节,能容纳一个14字节的以太网首部、一个40字节的IPv6首部、一个20字节的TCP首部以及22字节的数据,如果需要显示来自其他协议(如DNS或NFS)的额外信息,用户就得在运行tcpdump时增大该值。原创 2023-08-30 14:15:08 · 644 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十八章 原始套接字
原始套接字提供普通的TCP和UDP套接字不具备的以下3个能力:1.有了原始套接字,进程可以读写ICMPv4、IGMPv4、ICMPv6等分组。例如,ping程序就使用原始套接字发送ICMP回射请求并接收ICMP回射应答。多播路由守护程序mrouted也使用原始套接字发送和接收IGMPv4分组。这个能力还使得使用ICMP或IGMP的应用作为用户进程处理内核不认识的ICMP消息,而不用往内核中添加编码,例如路由器发现守护程序(Solaris 2.x上名为in.rdisc),它处理内核不认识的两个ICMP消息原创 2023-08-23 18:19:02 · 441 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十七章 IP选项
IPv4允许在20字节的首部固定部分后跟最多共40字节的选项。尽管已经定义了10种IPv4选项,但最常用的是源路径选项。我们可通过存取IP_OPTIONS套接字选项访问这些选项,我们存取该套接字选项时,所用的缓冲区中的值就是它们置于IP数据报中的格式。IPv6允许在固定长度40字节的IPv6首部之后,传输层首部(如ICMPv6、TCP、UDP)之前出现扩展首部,目前定义了6种扩展首部。与IPv4不同的是,IPv6扩展首部的访问途径是函数接口,而非强求用户理解这些首部如何呈现在IPv6分组中的真实细节。I原创 2023-08-08 18:22:26 · 692 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十六章 线程
把一个程序转换成使用线程的版本时,有时会碰到因有些函数使用静态变量而引起的编程错误,和许多线程相关的编程错误相同,这个错误也会引起非确定性的结果。当一个线程终止时,如上例中调用readline的线程终止时,readline函数已经分配了一个需要释放的内存区,这正是Key结构中的析构函数指针的用处,一个线程调用pthread_key_create创建某个线程特定数据时,所指定的函数之一就是指向某个析构函数的指针,当线程终止时,系统将扫描该线程的pkey数组,为每个非空的pkey指针调用相应的析构函数。原创 2023-07-31 22:38:52 · 395 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十五章 信号驱动式IO
考虑以下情形:一个数据报到达导致SIGIO被递交,它的信号处理函数读入该数据报并把它放到供主循环读取的队列中,但在信号处理函数执行期间,又有两个数据报到达,导致SIGIO再产生2次,由于SIGIO被阻塞,当它的信号处理函数返回时,该处理函数仅再被调用一次,该信号处理函数的第二次执行读入第二个数据报,第三个数据报仍会留在套接字接收队列,第三个数据报被读入的条件是第四个数据报到达,当第四个数据报到达时,被读入并放到供主循环读取的队列中的是第三个而非第四个数据报。UDP发生异步错误的前提是UDP套接字已连接。原创 2023-07-21 17:23:01 · 276 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十三章 高级SCTP套接字编程
第十章中编写的一到多式SCTP回射服务器程序不保持任何关联状态,它只是像UDP一样,调用sctp_recvmsg获取消息,然后调用sctp_sendmsg回射消息,这样设计依赖于客户关闭关联,如果客户打开一个关联后不发送任何数据,服务器还是会给这些客户分配资源,虽然这些客户不会使用这些资源,这些空闲的客户会无意造成对于SCTP的拒绝服务攻击,因此SCTP增设了自动关闭特性。SCTP忠实地保持消息边界,而当每个消息的长度仅仅是1字节时,SCTP封装这样的消息到数据块会导致过多的开销,效率非常低。原创 2023-07-13 23:25:56 · 562 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十二章 高级UDP套接字编程
TCP是一个字节流协议,又使用滑动窗口,因此没有记录边界或发送者数据发送能力超过接收者接受能力之类的事情,但对于UDP,每个输入操作对应一个UDP数据报(一个记录),因此当收取的数据报大于引用的输入缓冲区时就有问题。UDP是不可靠协议,但有些应用确实有理由使用UDP而非TCP,在这些UDP应用中,我们必须包含一些特性弥补UDP的不可靠性,如超时和重传(用于处理丢失的数据报)、序列号(用于匹配应答与请求)。如果实现不支持IP_RECVDSTADDR套接字选项,那么确定外来UDP数据报目的IP地址的方法之一原创 2023-07-05 22:05:52 · 422 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十一章 多播
单播地址标识单个IP接口,广播地址标识某个子网的所有IP接口,而多播地址标识一组IP接口。单播和广播是寻址方案的两个极端(要么单个要么全部),多播则意在两者之间提供一种折衷方案。多播数据报只应由对它感兴趣的接口接收,即由运行相应多播会话应用系统的主机上的接口接收。广播一般局限于局域网内使用,而多播既可用于局域网,也可跨广域网使用。事实上,基于MBone(Multicast Backbone,一种基于IP多播(IP Multicast)的网络基础设施,旨在支持多播数据传输,基于MBone构建的应用系统利用多播原创 2023-06-26 00:17:39 · 580 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二十章 广播
本书迄今为止的所有例子都是单播:一个进程与另一个进程通信。TCP只支持单播寻址,而UDP和原始IP还支持其他寻址类型,下图比较了不同的寻址方式:IPv6往寻址体系中增加了任播(anycasting)方式。RFC 1546讲述了一个IPv4任播版本,但它从未广泛部署过。IPv6任播定义在RFC 3513中。任播允许从一组通常提供相同服务的主机中选择一个(一般是选择按某种测度而言离源主机最近的)。通过适当的路由配置,主机可以在IPv4或IPv6中通过在多个位置向路由协议注入相同的地址(指的是将相同的地址信息原创 2023-06-15 23:17:09 · 757 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十九章 密钥管理套接字
sadb_sa_flags成员目前只定义了一个标志,即SADB_SAFLAGS_PFS,该标志要求完备前向安全(PFS,perfect forward security),即密钥的值不依赖于先前的密钥或某个主密钥,PFS确保即使长期的私钥泄露,先前的通信内容也无法被解密,在传统的加密协议中,使用的是长期有效的密钥,如果这些密钥被泄露,攻击者可以将其用于解密先前截获的通信数据,而PFS使用的是临时生成的一次性密钥,这些密钥仅用于加密和解密单个会话或通信。sadb_sa_replay指定反重放窗口的大小。原创 2023-06-08 23:32:56 · 641 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十八章 路由套接字
对于一个名为eth10且链路层地址是一个IEEE EUI-64地址的接口而言,它的数据链路套接字地址结构中的sdl_nlen成员将是5,sdl_alen成员将是8,整个sockaddr_dl结构需要21字节(sdl_data成员中含有接口名和链路层地址,共13字节),在32位体系结构上会向上舍入成24字节。2.NET_RT_FLAGS:返回由name[3]指定的地址族的路由表,但仅限于所带标志(若干个RTF_xxx常值的逻辑或)与name[5]指定的标志相匹配的路由表项。原创 2023-06-04 22:57:25 · 1241 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十三章 守护进程和inetd超级服务器
配置成wait时,表示inetd等子进程退出后再接受新连接请求(对于UDP服务器来说,inetd和由inetd启动的服务器进程使用的是同一个套接字,因此需要由inetd启动的服务器进程接管该套接字,直到服务结束),而nowait表示inetd不等子进程退出就接受新连接请求(相当于监听套接字没有被由inetd启动的守护进程接管)。通过创建一个Unix域套接字,我们就可以在自己的守护进程中通过syslogd绑定的路径名发送我们的消息,以达到发送日志消息的目的,但更简单的接口是下面要介绍的syslog函数。原创 2023-05-13 14:17:16 · 758 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十章 SCTP客户/服务器程序例子
这些后续分节的延迟递送确保接收应用进程能按顺序得到由发送进程发送的数据,但也有不好之处,假如在单个TCP连接上发送语义上独立的消息,如服务器可能发送3幅不同的图像供web浏览器显示,为了营造这几幅图像在用户屏幕上并行显示的效果,服务器先发送第一幅图片的一个断片,再发送第二幅图像的一个断片,然后再发送第三幅图像的一个断片,服务器重复此过程,直到3幅图像全部成功发送到浏览器。3.客户读到回射的行,然后将其打印在标准输出上,并列出流号、流序列号(用于标识一个数据块在它所在流中的序号)和新流号。原创 2023-03-22 01:26:53 · 287 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十七章 ioctl操作
以上程序中获取SIOCGIFCONF请求的结果时使用的是循环,这是因为,对于SIOCGIFOCNF请求,有些实现在缓冲区大小不足以存放结果时不返回错误,而是截断并返回成功,这意味着要知道缓冲区是否足够大的唯一方法是:发出请求,记下返回的长度,用更大的缓冲区发出请求,比较返回的长度和刚记下的长度,如果相同,我们的缓冲区才足够大。这些接口操作请求中许多使用套接字地址结构在应用进程和内核间指定或返回具体接口的IP地址或地址掩码,对于IPv4,这个地址或掩码存放在一个网际网套接字地址结构的sin_addr成员中;原创 2023-05-30 23:56:01 · 1195 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十六章 非阻塞式IO
总计耗时差不多减半,为15个时间单位,但这是理想情况下,如果并行执行的连接共享同一个低速链路(如客户主机通过一个拨号调制解调器链路接入因特网),那么每个连接可能彼此竞用有限的资源,使得每个连接耗用更长时间,例如,10个时间单位的连接可能变为15,15个时间单位的可能变成20,4个时间单位的可能变为6,即使这样,总计耗时将是21,仍短于串行执行。如果进程对一个阻塞的TCP套接字调用这些函数,且该套接字的接收缓存中没有数据可读,该进程将投入睡眠,直到有数据到达。这里特意采用与tcpdump的时间戳一致的格式。原创 2023-05-27 14:47:23 · 912 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十二章 IPv4与IPv6的互操作性
3.如果一个IPv6的TCP客户指定一个IPv4映射的IPv6地址以调用connect,或一个IPv6的UDP客户指定一个IPv4映射的IPv6地址以调用sendto,则内核检测到这个映射地址后,改为发送一个IPv4数据报而非IPv6数据报。3.如果服务器有一个IPv6监听套接字,且绑定在其上的是除IPv4映射的IPv6地址之外的某个非通配IPv6地址,或另一种情况,即绑定在其上的是IPv6通配地址,但设置了IPV6_V6ONLY套接字选项,则该套接字只能接受来自IPv6客户的外来连接。原创 2023-05-10 00:10:52 · 1022 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十四章 高级I/O函数
术语“事务”的含义是客户的请求与服务器的应答,常见的事务的例子有DNS请求与服务器的应答、HTTP请求与服务器的应答。就一个字节流套接字而言,其接收队列中的数据量可能在两次相继的recv调用之间发生变化,例如,指定MSG_PEEK标志以一个长为1024字节的缓冲区对一个TCP套接字调用recv,其返回值为100,如果再次调用同一个recv,返回值就可能超过100(假设接收缓冲区长度大于100),因为这两次recv调用之间TCP可能又收到一些数据。这个20字节缓冲区的后4个字节没有改动。原创 2023-05-20 00:22:18 · 801 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十五章 Unix域协议
先给出一个描述符传递的程序,名为mycat,它通过命令行参数获取一个路径名,打开这个文件,再把文件内容复制到标准输出,但该程序不是调用普通的open函数打开文件,而是调用我们的my_open函数,my_open创建一个流管道,并调用fork和exec执行另一个程序,该程序打开文件,并把打开描述符通过流管道传回父进程。这种技术要求首先在这两个进程间创建一个Unix域套接字,然后调用sendmsg跨这个套接字发送一个特殊消息,这个消息由内核处理,会把打开的描述符从发送进程传递到接收进程。原创 2023-05-23 18:35:30 · 773 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第十一章 名字与地址转换
到目前为止,本书中所有例子都用数值地址表示主机(如206.6.226.33),用数值端口号来标识服务器(如端口13代表daytime服务器)。但出于某些理由,我们应使用名字而非数值:名字比较容易记住;数值地址可以变动而名字保持不变;随着往IPv6上转移,数值地址变得非常长,手工键入数值地址更易出错。域名系统(Domain Name System,DNS)主要用于主机名和IP地址之间的映射。主机名既可以是一个简单名字(simple name),如solaris或bsdi,也可以是一个全限定域名(FQDN,F原创 2023-05-04 22:31:35 · 747 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第九章 基本SCTP套接字编程
7.SCTP_PARTIAL_DELIVERY_EVENT:有些应用会经由套接字缓冲区向用户传送大消息,如一个用户写一个大小为4MB的消息,可能会耗尽系统资源,如果SCTP实现不能在整个消息都写入前就开始把已写入部分递送给对端的机制,就无法处理这样的大消息,能够这样递送消息的机制称为部分递送API,部分递送API由SCTP这样调用:置空msg_flags字段发送一个消息的除最后一部分数据外的各部分数据,发送最后一部分数据时把msg_flags字段设为MSG_EOR。有些人用多到一代替一到多,两者可以互换。原创 2023-03-15 18:38:44 · 989 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第八章 基本UDP套接字编程
UDP是无连接不可靠的数据报协议,不同于TCP提供的面向连接的可靠字节流。使用UDP编写的常见程序有:DNS、NFS、SNMP。以下是典型的UDP客户/服务器程序的函数调用,客户不与服务器建立连接,而是只使用sendto函数给服务器发送数据报,发送时必须指定目的地的地址作为参数。服务器也不接受来自客户的连接,而是直接调用recvfrom函数,等待某个客户的数据到达,recvfrom函数将返回所接收的数据和客户的协议地址,从而服务器可以把响应发给正确的客户:这两个函数类似标准的read、write函数,但原创 2023-03-08 15:35:00 · 965 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第五章 TCP客户/服务器程序示例
本章将编写一个完整的TCP客户/服务器程序,这个简单例子是执行以下步骤的一个回射服务器:1.客户从标准输入读入一行文本,并写给服务器;2.服务器从网络输入读入这行文本,并回射给客户;3.客户从网络输入读入这行回射文本,并显示在标准输出上。如上图,我们在客户与服务器之间画了两个单向箭头,但实际上它们构成一个全双工的TCP连接。fets和fputs函数来自标准IO函数库,writen和readline这两个函数是我们编写的。大多数TCP/IP实现已经提供了以上这种回射服务器,有使用UDP的,也有使用T原创 2022-12-13 11:45:52 · 677 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第二章 传输层:TCP、UDP和SCTP
绝大多数客户/服务器网络应用使用TCP或UDP,SCTP(流控制传输协议,Stream Control Transmission Protocol)是一个较新的协议,最初设计用于通过因特网传输电话信令。这些传输层协议都使用网络层协议IP(IPv4或IPv6)。尽管可以绕过传输层直接使用IPv4或IPv6,但这种原始套接字极少使用。UDP是一个简单的、不可靠的数据报协议,而TCP是一个复杂、可靠的字节流协议。SCTP也是一个可靠地协议,但它还提供消息边界、传输层级别的多宿支持(即多个路径通往同一服务器)、将队原创 2022-10-21 23:40:35 · 1228 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第六章 I/O复用:select和poll函数
终止网络连接的通常方法是调用close函数,但它有两个限制:1.close函数把描述符的引用计数-1,仅在计数变为0时才关闭套接字,shutdown函数不管引用计数就激发TCP的正常连接终止序列。2.close函数终止读和写两个方向上的数据传送,shutdown函数可关闭一个方向上的数据传送。TCP是全双工的,有时需要告知对端我们已完成了数据发送,即使对端仍有数据要发送给我们。howto参数的值:1.SHUT_RD:关闭连接的读这一半,套接字接收缓冲区中的现有数据被丢弃。进程不能再对这样的套接字原创 2020-07-22 15:03:15 · 374 阅读 · 1 评论 -
UNIX网络编程卷一 学习笔记 第七章 套接字选项
有很多方法可以获取和设置套接字选项:1.getsockopt和setsockopt函数。2.fcntl函数。3.ioctl函数。fcntl函数是将套接字设为非阻塞式IO型、设为信号驱动式IO型、设置套接字属主的POSIX方法。这两个函数只用于套接字:以上函数用于获取或设置套接字选项。参数sockfd必须指向一个打开的套接字描述符。setsockopt函数从参数optval指向的内存中取得要设置的新值;getsockopt把要获取的选项当前值存放到参数optval指向的内存中。参数optval指向的原创 2020-07-17 15:17:02 · 619 阅读 · 1 评论 -
UNIX网络编程卷一 学习笔记 第四章 基本TCP套接字编程
为执行网络IO,要先调用socket函数指定期望的通信协议类型:family参数指明协议族,也被称为协议域:type参数指明套接字的类型:protocol参数:protocol也可设为0,表示给定的family和type组合的系统默认值。family和type的组合是否有效:...原创 2020-07-15 15:47:16 · 554 阅读 · 1 评论 -
UNIX网络编程卷一 学习笔记 第三章 套接字编程简介
每个协议族都定义它自己的套接字地址结构。这些地址的名字均以sockaddr_开头。IPv4套接字地址结构通常也称为网际套接字地址结构,名字是sockaddr_in,定义在netinet/in.h头文件中:长度字段sin_len简化了长度可变套接字地址结构的处理,它是为增加对OSI协议的支持而添加的。它是无符号短整数类型。不是每个厂家都支持该字段,POSIX规范也不要求有此字段。除非涉及路由套接字,否则无须设置和检查它。是否有长度字段可测试常量HAVE_SOCKADDR_SA_LEN确定,但这一常量不原创 2020-07-16 14:30:37 · 610 阅读 · 0 评论 -
UNIX网络编程卷一 学习笔记 第一章 简介
一般认为web服务器是一个长时间运行的程序(即守护程序),它只在响应来自网络的请求时才发送网络消息。大多网络应用都是由客户进程发起通信请求,确定这一点有助于简化协议和程序。一些较为复杂的网络还需异步回调通信,即由服务器向客户发起请求信息。通过网络通信的程序编写时要先确定程序相互通信所用的协议。一个服务器可同时处理多个客户请求。客户和服务器无需如上图一样都处于一个局域网,可通过路由器将两个局域网连接到广域网:最大的广域网是因特网。向服务器查询时间:#include <stdio.h&g原创 2020-07-10 22:47:54 · 646 阅读 · 1 评论