socket(2) - Linux 手册页

名称

socket - 创建通信端点

概要

#include <sys/types.h> /* 参见注意事项 */
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

描述

socket() 创建一个通信端点并返回一个描述符。

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 Appletalkddp(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_DGRAMSOCK_RAW 套接字允许向 sendto(2) 调用中指定的对应方发送数据报。数据报通常通过 recvfrom(2) 接收,该调用返回下一个数据报及其发送方的地址。

SOCK_PACKET 是一种过时的套接字类型,用于直接从设备驱动程序接收原始数据包。请改用 packet(7)

fcntl(2)F_SETOWN 操作可用于指定一个进程或进程组,以便在收到带外数据时接收 SIGURG 信号,或在 SOCK_STREAM 连接意外断开时接收 SIGPIPE 信号。此操作也可用于设置接收 I/O 以及通过 SIGIO 进行异步 I/O 事件通知的进程或进程组。使用 F_SETOWN 等同于调用带有 FIOSETOWNSIOCSPGRP 参数的 ioctl(2)

当网络向协议模块发出错误状况信号时(例如使用 IP 的 ICMP 消息),会为套接字设置挂起错误标志。对此套接字的下一次操作将返回挂起错误的错误代码。对于某些协议,可以启用每个套接字的错误队列以获取有关错误的详细信息;参见 ip(7) 中的 IP_RECVERR

套接字的操作由套接字级别的 选项 控制。这些选项定义在 <sys/socket.h> 中。函数 setsockopt(2)getsockopt(2) 分别用于设置和获取这些选项。

返回值

成功时,返回新套接字的文件描述符。失败时,返回 -1,并相应地设置 errno

错误

EACCES
拒绝创建指定类型和/或协议的套接字的权限。
EAFNOSUPPORT
该实现不支持指定的地址族。
EINVAL
未知协议,或协议族不可用。
EINVAL
type 中的标志无效。
EMFILE
进程文件表溢出。
ENFILE
已达到系统打开文件总数的限制。
ENOBUFSENOMEM
内存不足。在释放足够的资源之前无法创建套接字。
EPROTONOSUPPORT
此域内不支持该协议类型或指定的协议。

底层协议模块可能会产生其他错误。

符合

4.4BSD, POSIX.1-2001。

SOCK_NONBLOCKSOCK_CLOEXEC 标志是 Linux 特有的。

socket() 出现在 4.2BSD 中。它通常可移植到支持 BSD 套接字层克隆(包括 System V 变体)的非 BSD 系统。

说明

POSIX.1-2001 不要求包含 <sys/types.h>,且在 Linux 上也不需要此头文件。然而,一些历史(BSD)实现需要此头文件,编写可移植应用程序时包含它是明智的。

在 4.x BSD 下用于协议族的常量是 PF_UNIXPF_INET 等,而 AF_UNIXAF_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 卷。

引用自

accept4(2), acpi_listen(8), acpid(8), curl_easy_setopt(3), ei_connect(3), erl_connect(3), explain(1), explain(3), explain_socket(3), explain_socket_or_die(3), getifaddrs(3), getnameinfo(3), ident(3), if_nameindex(3), if_nametoindex(3), lwres_getaddrinfo(3), mknod(2), pmdaconnect(3), pmsocks(1), raw(7), rds(7), recvmmsg(2), sctp(7), sendfile(2), sendmmsg(2), socketcall(2), strobe(1), trickle(1)