为了执行网络I/0,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型(使用IPv4的TCP、使用IPv6的UDP、Unix域字节流协议等)。
#include <sys/socket.h>
int socket(int family, int type, int protocol);
返回值:若成功则返回非负描述符,否则返回-1
其中family参数指明协议族,它是图1中所示的某个常值。该参数也往往被称为协议域。type参数指明套接字类型,它是图2中所示的某个常值。protocol参数应设为图3所示的某个协议类型常值,或者设为0,以选择所给定family和type组合的系统默认值。
并非所有套接字family与type的组合都是有效的,图4给出了一些有效的组合和对应的真正的协议。其中标为“是”的项也是有效的,但还没有找到便捷的缩略词。而空白项则是无效组合。
family | 说明 |
AF_INET AF_INET6 AF_LOCAL AF_ROUTE AF_KEY | IPv4协议 IPv6协议 Unix域协议 路由套接字 秘钥套接字 |
图1 socket函数的family常值
type | 说明 |
SOCK_STREAM SOCK_DGRAM SOCK_SEQPACKET SOCK_RAW | 字节流套接字 数据报套接字 有序分组套接字 原始套接字 |
图2 socket函数的type常值
protocol | 说明 |
IPPROTO_TCP IPPROTO_UDP IPPROTO_SCTP | TCP传输协议 UDP传输协议 SCTP传输协议 |
图3 socket函数AF_INET或AF_INET6的protocol常值
图4 socket函数中family和type参数的组合
socket函数在成功时返回一个小的非负整数值,它与文件描述符类似,我们把它称为套接字描述符(socket descriptor)。为了得到这个套接字描述符,我们只是指定了协议族(IPv4、IPv6或Unix)和套接字类型(字节流、数据报或原始套接字)。我们并没有指定本地协议地址和远程协议地址。