SOCKET(2)

名字
socket - 建立一个用于交流的端点

概要
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

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

描述
socket() 建立一个用于交流的端点并且返回一个描述符。

The domain 参数指定一个通讯域名；选择的协议将会用于通讯。协议名在 <sys/socket.h> 中定义。 目前已知的格式包括：
名称 | 目的：手册页
 | unix(7) |
 | IPv4 网络协议 |
 | IPv6 网络协议 |
 | IPX - Novell 协议
 | 内核用户界面设备 |
 | ITU-T X.25 / ISO-8208 协议 |
 | Amateur radio AX.25 protocol |
 | Access to raw ATM PVCs |
 | Appletalk |
 | 底层包连接 |

套接字通过 type, 参数来确定通信语义。目前定义的类型有：

SOCK_STREAM
    提供有序的，可靠的，双向的，基于字节流的通讯。可能支持带外传输。

SOCK_DGRAM
    提供数据报（不面向连接的, 不可靠的固定最大长度的信息）。

SOCK_SEQPACKET
    提供有序的，可靠的，双向的，基于固定最大长度的数据报传输路径；需要一个读取整个伴有输入系统调用的包的用户。

SOCK_RAW
    提供未加工(raw)的网络协议通道。

SOCK_RDM
    提供可靠的数据报层，但是不保证顺序。

SOCK_PACKET
    废弃的，不应该在新的程序中使用，参考 packet(7)。

一些套接字类型并未被所有的协议实现； 例如， SOCK_SEQPACKET 并不被 AF_INET AF_INET 实现。

从 Linux 2.6.27 开始， type 参数可以提供其他的功能： 注意一些套接字类型可能包括一下值的或位，用来修改 socket(): 的行为。

SOCK_NONBLOCK
    设置 O_NONBLOCK 的标志于新打开的文件描述符。 通过这个标志可以不用调用 fcntl(2) 来达到相同的结果。

SOCK_CLOEXEC
    设置 close-on-exec (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 信号。这个操作也可能被用于让进程或进程组通过 SIGIO. 接收 I/O 和 I/O 不同步的通知。使用 F_SETOWN 等同于使用了 FIOSETOWN 或 SIOCSPGRP 参数的 ioctl(2) 系统调用。

当网络向协议模型发出一个错误情况的信号（例如，对IP使用ICMP消息），套接字将会设置上pending错误标志。对套接字接下去的操作将会返回pending错误的错误代码。对于一些协议，可能会为每一个接字接启用一个用于取出详细错误信息的错误列队； 参见 ip(7) 中的 IP_RECVERR 。

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

返回值
成功时，会返回新套接字的文件描述符。错误时，返回 -1 ，同时 errno 会被适当设置。

错误

EACCES
    不允许创建指定的 类型 和/或 指定的协议的套接字。

EAFNOSUPPORT
    工具不支持指定的地址。

EINVAL
    未知协议，或协议组不可用。

EINVAL
    错误的 type 标志。

EMFILE
    进程文件表溢出。

ENFILE
    已经达到系统上限的文件打开数。

ENOBUFS 或 ENOMEM
    没有足够的内存，直到有可用的资源套接字不能被创建。

EPROTONOSUPPORT
    协议类型或指定的协议不被当前域所支持。

其它的错误可能是由协议模型产生的。

兼容性
4.4BSD, POSIX.1-2001. SOCK_NONBLOCK 和 SOCK_CLOEXEC 标志是 Linux 特有的。 socket() appeared in 4.2BSD. 出现于 4.2BSD 。通常，非 BSD 系统的 BSD 套接字层克隆是可移植的（包括 System V 的变种）。

注意
并不要求包含 <sys/types.h> ，这个头文件在Linux下是不必须的。 可是一些历史上的 (BSD) 工具要求这个头文件，可移植程序很可能希望包含它。 4.x BSD下明显固定的协议组有 PF_UNIX， PF_INET， 等等，但是AF_UNIX等，它们是用于地址组的。可是BSD的man page保证“协议组一般等于地址组”，随后的标准在每个地方都使用了 AF_* 。 <sys/types.h> 文件头只在libc4以前是必须的。一些包，如util-linux，claim，是用于在所以Linux版本和库上可移植的。它们确实需要这个头文件。

例子
在 getaddrinfo(3)。 中有一个使用 socket() 的例子。

参见
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)

“An Introductory 4.3BSD Interprocess Communication Tutorial” 在 中被重印。

“BSD Interprocess Communication Tutorial” 在 UNIX Programmer's Supplementary Documents Volume 1 中被重印。

COLOPHON
This page is part of release 3.27 of the Linux man-pages project. A description of the project, and information about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. 译者于2011-07-26翻译，于2013-02-08修订 译文与原文的版权协议一致