个人网站租用服务器,手机网站开发者模式,无锡网站建设企业排名,深圳福永Socket 是网络协议栈暴露给编程人员的 API#xff0c;相比复杂的计算机网络协议#xff0c;API 对关键操作和配置数据进行了抽象#xff0c;简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍#xff0c;从而更好的理解 socket 编程。… Socket 是网络协议栈暴露给编程人员的 API相比复杂的计算机网络协议API 对关键操作和配置数据进行了抽象简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍从而更好的理解 socket 编程。 socket(7) send() 遵循 POSIX.1 - 2008 MSG_CONFIRM 是 Linux 扩展 1.库
标准 c 库libc, -lc
2.头文件
sys/socket.h
3.接口定义 sockfd socket(int socket_family, int socket_type, int protocol);
4.接口描述
续 【计算机网络】网络编程接口 Socket API 解读8
SO_PEEK_OFFLinux 3.4 后 这个选项目前只有 unix(7) 套接字支持在 recv(2) 系统调用使用了 MSG_PEEK 标记时可以用它来设置 “peek offset”即窥探偏移。 当这个选项值设置为负值时对于所有新套接字这个值都被设置为了 -1窥探行为会采用传统行为即携带 MSG_PEEK 标记的 recv(2) 会从队列头窥探数据。 当这个选项值大于等于 0 时那么下一次窥探位置就是这个选项指定的偏移地址。同时窥探偏移会加上之前已经偏移过的值这样下一次窥探才会返回队列中下一个数据。 如果 recv(2) 或者其他接口没有使用 MSG_PEEK 标记导致数据从队列头移出那么窥探偏移就会减去这个移出值。 换句话说不使用 MSG_PEEK 标记会导致窥探偏移调整以保持正确的相对位置保证后面窥探到的数据和没有移除数据时窥探到的数据相同。 对于数据报套接字如果窥探偏移指向了一个数据包的中间那么返回的数据会被标记为 MSG_TRUNC。 下面的例子解释 SO_PEEK_OFF 如何使用假如流套接字里排队的输入数据如下 aabbccddeeff 下面的 recv() 调用效果如注释所述 int ov 4; // Set peek offset to 4setsockopt(fd, SOL_SOCKET, SO_PEEK_OFF, ov, sizeof(ov));recv(fd, buf, 2, MSG_PEEK); // Peeks cc; offset set to 6recv(fd, buf, 2, MSG_PEEK); // Peeks dd; offset set to 8recv(fd, buf, 2, 0); // Reads aa; offset set to 6recv(fd, buf, 2, MSG_PEEK); // Peeks ee; offset set to 8
SO_PEERCRED 返回连接到套接字的对端进程的凭证。更多详细信息参考 unix(7)。
SO_PEERSECLinux 2.6.2 后 返回连接到套接字的对端进程的安全上下文。更多信息参考 unix(7)。
SO_PRIORITY 设置套接字上所有要发送数据包协议定义的优先级。Linux 使用这个值来给网络队列排序具有高优先级的数据包可以被优先处理依赖于选定设备的排队规则。设置超出 0~6 的优先级需要 CAP_NET_ADMIN 能力。
SO_PROTOCOLLinux 2.6.32 后 获得套接字协议值返回值类似 IPPROTO_SCTP 这样的整型值。参考 socket(2) 获取更多信息。这个套接字选项是只读的。
SO_RCVBUF 设置/获取最大套接字接收缓冲区大小字节数。当使用 setsockopt(2) 设置这个值时内核会使用这个值的两倍考虑到其他记录结构开销使用 getsockopt(2) 返回两倍的值。默认值在 /proc/sys/net/core/rmem_default 文件设置最大值由 /proc/sys/net/core/rmem_max 文件设置。最小值双倍的是 256。
SO_RCVBUFFORCELinux 2.6.14 后 具备 CAP_NET_ADMIN 能力的特权进程可以通过这个选项进行和 SO_RCVBUF 类似的设置但是这个可以设置 rmem_max 最大限制值。
SO_RCVLOWAT 和 SO_SNDLOWAT 设置套接字层将数据交由底层协议的最小缓冲量SO_SNDLOWAT以及用户接收到数据的最小值SO_RCVLOWAT。这两个值初始化为 1SO_SNDLOWAT 在 Linux 上不可改setsockopt(2) 会返回 ENOPROTOOPT 错误SO_RCVLOWAT 在 Linux 2.4 后可以修改。 Linux 2.6.28 之前Linux 上 select(2)/poll(2)/epoll(7) 不看 SO_RCVLOWAT 设置即使有一个字节也认为套接字是读就绪的接下来从套接字读取会阻塞直到 SO_RCVLOWAT 字节可用。Linux 2.6.28 后这几个接口只有在字节达到 SO_RCVLOWAT 值时才会套接字标记为读就绪。
SO_RCVTIMEO 和 SO_SNDTIMEO 指定接收和发送超时值参数是 struct timeval 类型。如果一个输入/输出函数阻塞这么长时间并且发送或者接收了一部分数据那么会返回已传输数据量如果没有传输任何数据那么会返回 -1 并设置 errno 为 EAGAIN 或者 EWOULDBLOCK或者套接字设置为非阻塞时返回 EINPROGRESS只对 connect(2) 有效。如果超时值设置为 0默认值那么对应操作永不超时。超时只对进行 I/O 操作的系统调用生效比如 accept(2)、connect(2)、read(2)、recvmsg(2)、send(2)、sendmsg(2)对于 select(2)、poll(2)、epoll_wait(2) 等无效。
SO_REUSEADDR 表示 bind(2) 中用于验证地址有效性的规则允许本地地址重用。对于 AF_INET 套接字套接字可以绑定到正在被监听的本地地址外的任何地址。当监听套接字绑定了到 INADDR_ANY 并指定了端口那么任何地址上都不能再绑定该端口。参数是一个整型布尔标记。
SO_REUSEPORTLinux 3.9 后 允许多个 AF_INET 或者 AF_INET6 套接字绑定到相同的套接字地址上。这个选项必须在 bind(2) 前设置到每个套接字上包括第一个套接字。为了防止端口劫持绑定到相同地址的所有进程必须具有相同的有效 UID。这个选项可以用于 TCP 和 UDP 套接字上。 对于 TCP 套接字这个选项允许 accept(2) 在多线程服务器上进行负载分配每个线程使用一个不同的监听套接字。这种方式比传统方式高效很多比如使用一个单线程进行 accept(2) 分配连接或者有多个线程在同一个套接字上进行 accept(2) 竞争。 对于 UDP 套接字比起传统的多个进程在同一个套接字上竞争接收数据报这种方式能够允许多进程线程对过来的数据报进行更好的负载分配。
SO_RXQ_OVFLLinux 2.6.33 后 表示需要携带一个 32 位的辅助消息来接收 skbsskbs 是自从套接字创建以来丢包总数。
SO_SELECT_ERR_QUEQUELinux 3.10 后 设置这个选项的套接字套接字上的错误不仅仅会通过 select(2) 的 exceptfds 通知同样 poll(2) 也会在返回 POLLERR 事件时返回一个 POLLPRI 错误。
5.示例代码 下面是一个 getsockopt 函数的使用代码
int rc;
int s;
int option_value;
int option_len;
struct linger l;
int getsockopt(int s, int level, int option_name,
char *option_value,int *option_len);⋮
/* Is out-of-band data in the normal input queue? */
option_len sizeof(int);
rc getsockopt(s, SOL_SOCKET, SO_OOBINLINE, (
char *) option_value, option_len);
if (rc 0)
{if (option_len sizeof(int)){if (option_value)/* yes it is in the normal queue */else/* no it is not*/}
}⋮
/* Do I linger on close? */
option_len sizeof(l);
rc getsockopt(s, SOL_SOCKET, SO_LINGER, (char *) l, option_len);
if (rc 0)
{if (option_len sizeof(l)){if (l.l_onoff)/* yes I linger */else/* no I do not */}
}