浅析LinuxSocket套接字编程中的 5 个隐患
隐患 1.忽略返回状态第一个隐患很明显 , 但它是开发新手最容易犯的一个错误 。 如果您忽略函数的返回状态 , 当它们失败或部分成功的时候 , 您也许会迷失 。 反过来 , 这可能传播错误 , 使定位问题的源头变得困难 。
捕获并检查每一个返回状态 , 而不是忽略它们 。 考虑清单 1 显示的例子 , 一个套接字 send 函数 。
忽略 API 函数返回状态
int status, sock, mode;/* Create a new stream (TCP) socket */sock = socket( AF_INET, SOCK_STREAM, 0 );...status = send( sock, buffer, buflen, MSG_DONTWAIT );if (status == -1) {/* send failed */printf( "send failed: %s\n", strerror(errno) );} else {/* send succeeded -- or did it? */} 探究一个函数片断 , 它完成套接字 send 操作(通过套接字发送数据) 。 函数的错误状态被捕获并测试 , 但这个例子忽略了 send 在无阻塞模式(由 MSG_DONTWAIT 标志启用)下的一个特性 。
send API 函数有三类可能的返回值:
- 如果数据成功地排到传输队列 , 则返回 0 。
- 如果排队失败 , 则返回 -1(通过使用 errno 变量可以了解失败的原因) 。
- 如果不是所有的字符都能够在函数调用时排队 , 则最终的返回值是发送的字符数 。
隐患 2.对等套接字闭包UNIX 有趣的一面是您几乎可以把任何东西看成是一个文件 。 文件本身、目录、管道、设备和套接字都被当作文件 。 这是新颖的抽象 , 意味着一整套的 API 可以用在广泛的设备类型上 。
考虑 read API 函数 , 它从文件读取一定数量的字节 。 read 函数返回读取的字节数(最高为您指定的最大值);或者 -1 , 表示错误;或者 0 , 如果已经到达文件末尾 。
如果在一个套接字上完成一个 read 操作并得到一个为 0 的返回值 , 这表明远程套接字端的对等层调用了 close API 方法 。 该指示与文件读取相同 —— 没有多余的数据可以通过描述符读取 。
适当处理 read API 函数的返回值
int sock, status;sock = socket( AF_INET, SOCK_STREAM, 0 );...status = read( sock, buffer, buflen );if (status > 0) {/* Data read from the socket */} else if (status == -1) {/* Error, check errno, take action... */} else if (status == 0) {/* Peer closed the socket, finish the close */close( sock );/* Further processing... */}同样 , 可以用 write API 函数来探测对等套接字的闭包 。 在这种情况下 , 接收 SIGPIPE 信号 , 或如果该信号阻塞 , write函数将返回 -1 并设置 errno 为 EPIPE 。需要C/C++ Linux高级服务器架构师学习资料私信“资料”(资料包括C/C++ , Linux , golang技术 , Nginx , ZeroMQ , MySQL , Redis , fastdfs , MongoDB , ZK , 流媒体 , CDN , P2P , K8S , Docker , TCP/IP , 协程 , DPDK , ffmpeg等) , 免费分享
文章插图隐患 3.地址使用错误(EADDRINUSE) 您可以使用 bind API 函数来绑定一个地址(一个接口和一个端口)到一个套接字端点 。 可以在服务器设置中使用这个函数 , 以便限制可能有连接到来的接口 。 也可以在客户端设置中使用这个函数 , 以便限制应当供出去的连接所使用的接口 。 bind 最常见的用法是关联端口号和服务器 , 并使用通配符地址(INADDR_ANY) , 它允许任何接口为到来的连接所使用 。
bind 普遍遭遇的问题是试图绑定一个已经在使用的端口 。 该陷阱是也许没有活动的套接字存在 , 但仍然禁止绑定端口(bind 返回 EADDRINUSE) , 它由 TCP 套接字状态 TIME_WAIT 引起 。 该状态在套接字关闭后约保留 2 到 4 分钟 。 在 TIME_WAIT 状态退出之后 , 套接字被删除 , 该地址才能被重新绑定而不出问题 。
推荐阅读
- vue2.x与vue3.x语法对比浅析
- USB接口中的皇帝!浅析雷电Thunderbolt的前生今世
- 浅析人工智能在行政领域的应用及其风险规制
- Python基础变量类型——List浅析
- 天猫入驻|天猫入驻:知舟集团浅析买天猫店好还是入驻好
