说在前面
- 环境: ubuntu16.04
- 参考: UNIX网络编程、linux manual page
- 其他:典型事件以及相关函数事件流程图
基本说明
为执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型。
-
定义
参数说明:#include <sys/socket.h> int socket(int domain, int type, int protocol); //栗子:int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- domain
指明协议域(或协议族)
该参数还有其他值例如PF_xxx、AF_NS(很少使用)、AF_ISO(很少使用);domain 说明 AF_INET IPv4协议 AF_INET6 IPv6协议 AF_LOCAL UNIX域协议 AF_ROUTE 路由套接字 AF_KEY 密钥套接字 - type
指明套接字类型
该参数还有其他值如SOCK_PACKET;type 说明 SOCK_STREAM 字节流套接字 SOCK_DGRAW 数据报套接字 SOCK_SEQPACKET 有序分组套接字 SOCK_RAW 原始套接字 - protocol
指定协议
该参数可设置为0,此时由前两个参数(domain、type)指定协议,其组合如下:protocol 说明 IPPROTO_TCP TCP传输协议 IPPROTO_UDP UDP传输协议 IPPROTO_SCTP SCTP传输协议 AF_INET AF_INET6 AF_LOCAL AF_ROUTE AF_KEY SOCK_STREAM TCP/SCTP TCP/SCTP 组合有效 组合无效 组合无效 SOCK_DGRAW UDP UDP 组合有效 组合无效 组合无效 SOCK_SEQPACKET SCTP SCTP 组合有效 组合无效 组合无效 SOCK_RAW IPv4 IPv6 组合无效 组合有效 组合有效
- 函数成功时,返回一个小的非负整数,称之为套接字描述符(socket descriptor),简称sockfd。该套接字描述符只需要指定协议族(IPv4、IPv6、UNIX)和套接字类型(字节流、数据报、原始套接字),不需要指定本地或者远程IP地址。
- 函数失败时,返回-1并设置errno
- domain
AF_xxx对比PF_xxx
- AF_前缀表示地址族;PF_前缀表示协议族。
历史上曾经有这样的想法:单个协议族可以支持多个地址族,PF_值用来创建套接字,而AF_值用于套接字地址结构。但实际上,支持多个地址族的协议族从来就未实现过,而且头文件<sys/socket.h>中为一给定协议定的PF_值总是与此协议的AF_值相等,,,