LinuxSocket套接字出现问题怎么办?教你5个方法“有备无患”

LinuxSocket套接字出现问题怎么办?教你5个方法“有备无患”

2023年7月23日发(作者:)

LinuxSocket套接字出现问题怎么办?教你5个⽅法“有备⽆患”在 4.2 BSD UNIX® 操作系统中⾸次引⼊,Sockets API 现在是任何操作系统的标准特性。事实上,很难找到⼀种不⽀持 Sockets API 的现代语⾔。该 API 相当简单,但新的开发⼈员仍然会遇到⼀些常见的隐患。本⽂识别那些隐患并向您显⽰如何避开它们。

隐患 1.忽略返回状态第⼀个隐患很明显,但它是开发新⼿最容易犯的⼀个错误。如果您忽略函数的返回状态,当它们失败或部分成功的时候,您也许会迷失。反过来,这可能传播错误,使定位问题的源头变得困难。捕获并检查每⼀个返回状态,⽽不是忽略它们。考虑清单 1 显⽰的例⼦,⼀个套接字 send 函数。

忽略 API 函数返回状态探究⼀个函数⽚断,它完成套接字 send 操作(通过套接字发送数据)。函数的错误状态被捕获并测试,但这个例⼦忽略了 send 在⽆阻塞模式(由 MSG_DONTWAIT 标志启⽤)下的⼀个特性。

send API 函数有三类可能的返回值:如果数据成功地排到传输队列,则返回 0。如果排队失败,则返回 -1(通过使⽤ errno 变量可以了解失败的原因)。如果不是所有的字符都能够在函数调⽤时排队,则最终的返回值是发送的字符数。由于 send 的 MSG_DONTWAIT 变量的⽆阻塞性质,函数调⽤在发送完所有的数据、⼀些数据或没有发送任何数据后返回。在这⾥忽略返回状态将导致不完全的发送和随后的数据丢失。隐患 2.对等套接字闭包UNIX 有趣的⼀⾯是您⼏乎可以把任何东西看成是⼀个⽂件。⽂件本⾝、⽬录、管道、设备和套接字都被当作⽂件。这是新颖的抽象,意味着⼀整套的 API 可以⽤在⼴泛的设备类型上。考虑 read API 函数,它从⽂件读取⼀定数量的字节。read 函数返回读取的字节数(最⾼为您指定的最⼤值);或者 -1,表⽰错误;或者 0,如果已经到达⽂件末尾。如果在⼀个套接字上完成⼀个 read 操作并得到⼀个为 0 的返回值,这表明远程套接字端的对等层调⽤了 close API ⽅法。该指⽰与⽂件读取相同 —— 没有多余的数据可以通过描述符读取。适当处理 read API 函数的返回值同样,可以⽤ write API 函数来探测对等套接字的闭包。在这种情况下,接收 SIGPIPE 信号,或如果该信号阻塞,write函数将返回 -1 并设置 errno 为 EPIPE。

隐患 3.地址使⽤错误(EADDRINUSE)您可以使⽤ bind API 函数来绑定⼀个地址(⼀个接⼝和⼀个端⼝)到⼀个套接字端点。可以在服务器设置中使⽤这个函数,以便限制可能有连接到来的接⼝。也可以在客户端设置中使⽤这个函数,以便限制应当供出去的连接所使⽤的接⼝。bind 最常见的⽤法是关联端⼝号和服务器,并使⽤通配符地址(INADDR_ANY),它允许任何接⼝为到来的连接所使⽤。bind 普遍遭遇的问题是试图绑定⼀个已经在使⽤的端⼝。该陷阱是也许没有活动的套接字存在,但仍然禁⽌绑定端⼝(bind 返回 EADDRINUSE),它由 TCP 套接字状态 TIME_WAIT 引起。该状态在套接字关闭后约保留 2 到 4 分钟。在 TIME_WAIT 状态退出之后,套接字被删除,该地址才能被重新绑定⽽不出问题。等待 TIME_WAIT 结束可能是令⼈恼⽕的⼀件事,特别是如果您正在开发⼀个套接字服务器,就需要停⽌服务器来做⼀些改动,然后重启。幸运的是,有⽅法可以避开 TIME_WAIT 状态。可以给套接字应⽤ SO_REUSEADDR 套接字选项,以便端⼝可以马上重⽤。考虑下⾯的例⼦。在绑定地址之前,我以 SO_REUSEADDR 选项调⽤ setsockopt。为了允许地址重⽤,我设置整型参数(on)为 1 (不然,可以设为 0 来禁⽌地址重⽤)。使⽤ SO_REUSEADDR 套接字选项避免地址使⽤错误在应⽤了 SO_REUSEADDR 选项之后,bind API 函数将允许地址的⽴即重⽤。隐患 4.发送结构化数据套接字是发送⽆结构⼆进制字节流或 ASCII 数据流(⽐如 HTTP 上的 HTTP 页⾯,或 SMTP 上的电⼦邮件)的完美⼯具。但是如果试图在⼀个套接字上发送⼆进制数据,事情将会变得更加复杂。⽐如说,您想要发送⼀个整数:您可以肯定,接收者将使⽤同样的⽅式来解释该整数吗?运⾏在同⼀架构上的应⽤程序可以依赖它们共同的平台来对该类型的数据做出相同的解释。但是,如果⼀个运⾏在⾼位优先的 IBM PowerPC 上的客户端发送⼀个 32 位的整数到⼀个低位优先的 Intel x86,那将会发⽣什么呢?字节排列将引起不正确的解释。字节交换还是不呢?Endianness 是指内存中字节的排列顺序。⾼位优先(big endian) 按最⾼有效字节在前排列,然⽽ 低位优先(little endian) 按照最低有效字节在前排序。⾼位优先架构(⽐如 PowerPC®)⽐低位优先架构(⽐如 Intel® Pentium® 系列,其⽹络字节顺序是⾼位优先)有优势。这意味着,对⾼位优先的机器来说,在 TCP/IP 内控制数据是⾃然有序的。低位优先架构要求字节交换 —— 对⽹络应⽤程序来说,这是⼀个轻微的性能弱点。通过套接字发送⼀个 C 结构会怎么样呢?这⾥,也会遇到⿇烦,因为不是所有的编译器都以相同的⽅式排列⼀个结构的元素。结构也可能被压缩以便使浪费的空间最少,这进⼀步使结构中的元素错位。幸好,有解决这个问题的⽅案,能够保证两端数据的⼀致解释。过去,远程过程调⽤(Remote Procedure Call,RPC)套装⼯具提供所谓的外部数据表⽰(External DataRepresentation,XDR)。XDR 为数据定义⼀个标准的表⽰来⽀持异构⽹络应⽤程序通信的开发。现在,有两个新的协议提供相似的功能。可扩展标记语⾔/远程过程调⽤(XML/RPC)以 XML 格式安排 HTTP 上的过程调⽤。数据和元数据⽤ XML 进⾏编码并作为字符串传输,并通过主机架构把值和它们的物理表⽰分开。SOAP 跟随 XML-RPC,以更好的特性和功能扩展了它的思想。隐患 中的帧同步假定TCP 不提供帧同步,这使得它对于⾯向字节流的协议是完美的。这是 TCP 与 UDP(User Datagram Protocol,⽤户数据报协议)的⼀个重要区别。UDP 是⾯向消息的协议,它保留发送者和接收者之间的消息边界。TCP 是⼀个⾯向流的协议,它假定正在通信的数据是⽆结构的,如图 1所⽰。UDP 的帧同步能⼒和缺乏帧同步的 TCP图 的上部说明⼀个 UDP 客户端和服务器。左边的对等层完成两个套接字的写操作,每个 100 字节。协议栈的 UDP 层追踪写的数量,并确保当右边的接收者通过套接字获取数据时,它以同样数量的字节到达。换句话说,为读者保留了写者提供的消息边界。现在,看图的底部.它为 TCP 层演⽰了相同粒度的写操作。两个独⽴的写操作(每个 100 字节)写⼊流套接字。但在本例中,流套接字的读者得到的是 200 字节。协议栈的 TCP 层聚合了两次写操作。这种聚合可以发⽣在 TCP/IP 协议栈的发送者或接收者中任何⼀⽅。重要的是,要注意到聚合也许不会发⽣ —— TCP 只保证数据的有序发送。对⼤多数开发⼈员来说,该陷阱会引起困惑。您想要获得 TCP 的可靠性和 UDP 的帧同步。除⾮改⽤其他的传输协议,⽐如流传输控制协议(STCP),否则就要求应⽤层开发⼈员来实现缓冲和分段功能。查看⽹络⼦系统的细节netstat ⼯具提供查看 GNU/Linux ⽹络⼦系统的能⼒。使⽤ netstat,可以查看当前活动的连接(按单个协议进⾏查看),查看特定状态的连接(⽐如处于监听状态的服务器套接字)和许多其他的信息。 netstat 提供的⼀些选项和它们启⽤的特性。

netstat 实⽤程序的⽤法模式尽管存在许多其他的实⽤程序,但 netstat 的功能很全⾯,它覆盖了 route、ifconfig 和其他标准 GNU/Linux ⼯具的功能。

监视流量可以使⽤ GNU/Linux 的⼏个⼯具来检查⽹络上的低层流量。tcpdump ⼯具是⼀个⽐较⽼的⼯具,它从⽹上“嗅探”⽹络数据包,打印到 stdout 或记录在⼀个⽂件中。该功能允许查看应⽤程序产⽣的流量和 TCP ⽣成的低层流控制机制。⼀个叫做 tcpflow 的新⼯具与 tcpdump 相辅相成,它提供协议流分析和适当地重构数据流的⽅法,⽽不管数据包的顺序或重发。 tcpdump的两个⽤法模式。cpdump ⼯具的⽤法模式tcpdump 和 tcpflow ⼯具有⼤量的选项,包括创建复杂过滤表达式的能⼒。tcpdump 和 tcpflow 都是基于⽂本的命令⾏⼯具。如果您更喜欢图形⽤户界⾯(GUI),有⼀个开放源码⼯具 Ethereal 也许适合您的需要。Ethereal 是⼀个专业的协议分析软件,它可以帮助调试应⽤层协议。它的插⼊式架构(plug-in architecture)可以分解协议,⽐如 HTTP 和您能想到的任何协议(写本⽂的时候共有 637 个协议)。总结套接字编程是容易⽽有趣的,但是您要避免引⼊错误或⾄少使它们容易被发现,这就需要考虑本⽂中描述的这 5 个常见的陷阱,并且采⽤标准的防错性程序设计实践。GNU/Linux ⼯具和实⽤程序还可以帮助发现⼀些程序中的⼩问题。记住:在查看实⽤程序的帮助⼿册时候,跟踪相关的或“请参见”⼯具。您也许会发现⼀个必要的新⼯具。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690106083a306282.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信