socket(2) - Linux 手册页
名称
socket - 创建通信端点概要
#include <sys/types.h> /* 参见注意事项 */#include <sys/socket.h>
int socket(int domain, int type, int protocol);
描述
domain 参数指定通信域;这决定了将用于通信的协议族。这些协议族在 <sys/socket.h> 中定义。当前支持的格式包括:
| 名称 | 目的 | 手册页 |
| AF_UNIX, AF_LOCAL | 本地通信 | unix(7) |
| AF_INET | IPv4 Internet 协议 | ip(7) |
| AF_INET6 | IPv6 Internet 协议 | ipv6(7) |
| AF_IPX | IPX - Novell 协议 | |
| AF_NETLINK | 内核用户界面设备 | netlink(7) |
| AF_X25 | ITU-T X.25 / ISO-8208 协议 | x25(7) |
| AF_AX25 | 业余无线电 AX.25 协议 | |
| AF_ATMPVC | 原始 ATM PVC 访问 | |
| AF_APPLETALK | Appletalk | ddp(7) |
| AF_PACKET | 底层数据包接口 | 数据包(7) |
套接字具有指定的 type,该参数指定了通信语义。当前定义的类型有:
- SOCK_STREAM
- 提供有序、可靠、双向、基于连接的字节流。支持带外数据传输机制。
- SOCK_DGRAM
- 支持数据报(无连接、不可靠的固定最大长度消息)。
- SOCK_SEQPACKET
- 为固定最大长度的数据报提供有序、可靠、双向、基于连接的传输路径;使用者在每次输入系统调用时必须读取整个数据包。
- SOCK_RAW
- 提供原始网络协议访问。
- SOCK_RDM
- 提供不保证顺序的可靠数据报层。
- SOCK_PACKET
- 已过时,不应在新程序中使用;请参阅 packet(7)。
某些套接字类型可能并非由所有协议族实现;例如,AF_INET 不支持 SOCK_SEQPACKET。
从 Linux 2.6.27 开始,type 参数具有第二种用途:除了指定套接字类型外,还可以通过按位“或”(OR)操作包含以下值,以修改 socket() 的行为:
- SOCK_NONBLOCK
- 在新打开的文件描述上设置 O_NONBLOCK 文件状态标志。使用此标志可节省额外的 fcntl(2) 调用。
- SOCK_CLOEXEC
- 在新文件描述符上设置执行时关闭 (FD_CLOEXEC) 标志。有关此标志的用途,请参阅 open(2) 中关于 O_CLOEXEC 标志的说明。
protocol 指定套接字使用的特定协议。通常,在给定的协议族内只有一个协议支持特定的套接字类型,这种情况下 protocol 可指定为 0。然而,也可能存在多个协议,此时必须按此方式指定特定协议。所使用的协议编号特定于进行通信的“通信域”;详见 protocols(5)。有关如何将协议名称字符串映射为协议编号,请参阅 getprotoent(3)。
SOCK_STREAM 类型的套接字是全双工字节流,类似于管道。它们不保留记录边界。流套接字在发送或接收任何数据之前必须处于 连接 (connected) 状态。到另一个套接字的连接通过 connect(2) 调用创建。一旦连接,即可使用 read(2) 和 write(2) 调用,或 send(2) 和 recv(2) 的变体来传输数据。会话结束时可执行 close(2)。带外数据也可按 send(2) 所述进行传输,并按 recv(2) 所述进行接收。
实现 SOCK_STREAM 的通信协议确保数据不丢失或重复。如果对端协议有缓冲区空间,但数据未能在合理时间内成功传输,则连接被视为已死。当套接字启用 SO_KEEPALIVE 时,协议会以协议特定的方式检查另一端是否仍然存活。如果进程在断开的流上发送或接收数据,会引发 SIGPIPE 信号;这会导致未处理该信号的简单进程退出。SOCK_SEQPACKET 套接字使用与 SOCK_STREAM 套接字相同的系统调用。唯一的区别是 read(2) 调用仅返回请求数量的数据,到达数据包中剩余的数据将被丢弃。此外,传入数据报中的所有消息边界都会被保留。
SOCK_DGRAM 和 SOCK_RAW 套接字允许向 sendto(2) 调用中指定的对应方发送数据报。数据报通常通过 recvfrom(2) 接收,该调用返回下一个数据报及其发送方的地址。
SOCK_PACKET 是一种过时的套接字类型,用于直接从设备驱动程序接收原始数据包。请改用 packet(7)。
fcntl(2) 的 F_SETOWN 操作可用于指定一个进程或进程组,以便在收到带外数据时接收 SIGURG 信号,或在 SOCK_STREAM 连接意外断开时接收 SIGPIPE 信号。此操作也可用于设置接收 I/O 以及通过 SIGIO 进行异步 I/O 事件通知的进程或进程组。使用 F_SETOWN 等同于调用带有 FIOSETOWN 或 SIOCSPGRP 参数的 ioctl(2)。
当网络向协议模块发出错误状况信号时(例如使用 IP 的 ICMP 消息),会为套接字设置挂起错误标志。对此套接字的下一次操作将返回挂起错误的错误代码。对于某些协议,可以启用每个套接字的错误队列以获取有关错误的详细信息;参见 ip(7) 中的 IP_RECVERR。
套接字的操作由套接字级别的 选项 控制。这些选项定义在 <sys/socket.h> 中。函数 setsockopt(2) 和 getsockopt(2) 分别用于设置和获取这些选项。
返回值
成功时,返回新套接字的文件描述符。失败时,返回 -1,并相应地设置 errno。错误
- EACCES
- 拒绝创建指定类型和/或协议的套接字的权限。
- EAFNOSUPPORT
- 该实现不支持指定的地址族。
- EINVAL
- 未知协议,或协议族不可用。
- EINVAL
- type 中的标志无效。
- EMFILE
- 进程文件表溢出。
- ENFILE
- 已达到系统打开文件总数的限制。
- ENOBUFS 或 ENOMEM
- 内存不足。在释放足够的资源之前无法创建套接字。
- EPROTONOSUPPORT
- 此域内不支持该协议类型或指定的协议。
底层协议模块可能会产生其他错误。
符合
4.4BSD, POSIX.1-2001。SOCK_NONBLOCK 和 SOCK_CLOEXEC 标志是 Linux 特有的。
socket() 出现在 4.2BSD 中。它通常可移植到支持 BSD 套接字层克隆(包括 System V 变体)的非 BSD 系统。
说明
POSIX.1-2001 不要求包含 <sys/types.h>,且在 Linux 上也不需要此头文件。然而,一些历史(BSD)实现需要此头文件,编写可移植应用程序时包含它是明智的。在 4.x BSD 下用于协议族的常量是 PF_UNIX、PF_INET 等,而 AF_UNIX、AF_INET 等用于地址族。然而,BSD 手册页早已承诺:“协议族通常与地址族相同”,随后的标准在各处都使用了 AF_*。
示例
socket() 的使用示例请参见 getaddrinfo(3)。参见
accept(2), bind(2), connect(2), fcntl(2), getpeername(2), getsockname(2), getsockopt(2), ioctl(2), listen(2), read(2), recv(2), select(2), send(2), shutdown(2), socketpair(2), write(2), getprotoent(3), ip(7), socket(7), tcp(7), udp(7), unix(7)《4.3BSD 进程间通信入门教程》和《BSD 进程间通信教程》,转载于《UNIX 程序员补充文档》第 1 卷。