1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
int socket(int domain, int type, int protocol);
// 1) domain 参数:互联网协议族,常用的有以下
// AF_INET: 表示通过IPv4,通信方式(通过IPv4网络连接起来的主机),应用程序间的通信(32位IPv4地址+16位端口号),地址结构(sockaddr_in)
// AF_INET6:表示通过IPv6,通信方式(通过IPv6网络连接起来的主机),应用程序间的通信(128位Ipv6地址+16位端口号),地址结构(sockaddr_in6)
// AF_UNIX: 内核中,同一主机间通信,地址格式(路径名),地址结构(sockaddr_un)
// AF_ROUTE:路由套接字
// AF_KEY:密钥套接字
// AF_UNSPEC:未指定
// AF:是“Address Family”的简写,INET是“Inetnet”的简写
// 2) type 参数:表示 数据传输方式/套接字类型
// SOCK_STREAM:表示使用 "流格式套接字/面向连接的套接字",有序的、面向连接的、可靠的双向通信的字节流通信
// SOCK_DGRAM: 表示使用 "数据报套接字/无连接的套接字",不连接、不可靠、固定长度的数据报通信
// SOCK_NONBLOCK:将socket函数返回的文件描述符指定为非阻塞,可以和上面的宏使用’|’运算(如采用SOCK_STREAM | SOCK_NONBLOCK表示使用TCP协议且是非阻塞),默认是阻塞模式
// SOCK_RDM:表示想使用原始网络通信(如当domain参数设置为PF_INET时就表示直接使用TCP/IP协议族中的ip协议)
// SOCK_CLOEXEC:一旦进程exec执行新程序时,自动关闭socket返回的套接字文件描述符,也就是fork的程序不能共用一个socket
// 3) protocol 参数:表示传输协议,常用的有以下
// IPPROTO_TCP: 表示TCP传输协议
// IPPTOTO_UDP: 表示UDP传输协议
// IPPROTO_SCTP:表示SCTP传输协议
// IPPROTO_TIPC:表示TIPC传输协议
// 一般该参数默认传入0,socket程序根据前两个参数自动推断类型
// 返回值:成功时返回创建的socket的文件描述符;失败时返回-1,并设置errno错误信息
// 有了地址类型和数据传输方式,还不足以决定采用哪种协议吗?为什么还需要第三个参数呢?
// 1. 一般情况下有了前两个参数就可以创建socket,操作系统会自动推演出协议类型
// 2. 除非遇到这样的情况:有两种不同的协议支持同一种地址类型和数据传输类型
// 3. 如果我们不指明使用哪种协议,操作系统是没办法自动推演的
// int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 满足前面两个参数的只有TCP协议,因此可以写成如下
// int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
// int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// 满足前面两个参数的只有UDP协议,因此可以写成如下
// int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
|