背景:在muduo网络库中,用到两个获取socktes的方法,其中的参数不尽相同。
代码:
int sockets::createNonblockingOrDie(sa_family_t family) { #if VALGRIND int sockfd = ::socket(family, SOCK_STREAM, IPPROTO_TCP); if (sockfd < 0) { LOG_SYSFATAL << "sockets::createNonblockingOrDie"; } setNonBlockAndCloseOnExec(sockfd); #else int sockfd = ::socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP); if (sockfd < 0) { LOG_SYSFATAL << "sockets::createNonblockingOrDie"; } #endif return sockfd; }
这个函数的功能是获取用于建立socket连接的文件描述符。 关键的代码是里面的用于获取文件描述符的函数:
int sockfd = ::socket(family, SOCK_STREAM, IPPROTO_TCP);
int sockfd = ::socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);
其中 family 用于指定本次连接的类型 是ipv4还是ipv6或者是本地协议族。
family 的取值类型如下:
IPv4 | PF_INET |
IPv6 | PF_INET6 |
本地协议族 | PF_UNIX |
第二个参数,假设命名为type。 它的作用是指定服务类型。主要的服务类型有:
1. SOCK_STREAM服务(流服务)
2. SOCK_DGRAM(数据服务)
区别:一个面向数据流一个面向数据报
对于TCP/IP协议族而言,其取值SOCK_STREAM表示传输层使用TCP协议, 取SOCK_DGRAM表示使用UDP协议。
特别注意的是,自LINUX内核版本2.6.17起,type可以接受以下两个值: SOCK_NONBLOCK和SOCK_CLOEXEC。
它们分别表示将新创建的socket设为非阻塞的和用fork调用创建子进程时在子进程中关闭该socket。
第三个参数,假设命名为protocol
作用:在前面两个参数构成的集合下再选择一个具体的协议。
这个值几乎可以肯定是唯一的 通常是0,表示使用默认的协议。 前面两个参数几乎可以确定使用的协议 比如ipv4下的TCP协议 或 ipv4下的UDP协议。
返回值:
成功:返回一个socket文件描述符。
失败:返回-1 并设置error
原文:https://www.cnblogs.com/xiongxinxzy/p/13780562.html