Socket 基础

创建 socket 使用 socket(int domain, int type, int protocol) 函数,三个参数决定了 socket 的类型和特性。

协议族(domain/address family)
主要协议族包括:
    ​​AF_INET / PF_INET​​:IPv4 协议
    ​​AF_INET6 / PF_INET6​​:IPv6 协议
    ​​AF_UNIX / PF_UNIX​​:Unix 域协议(本地通信)
    ​​AF_PACKET / PF_PACKET​​:底层数据包接口
    ​​AF_NETLINK​​:内核与用户空间通信
    ​​AF_X25​​:X.25 协议
    ​​AF_AX25​​:Amateur Radio AX.25 协议
    ​​AF_ATMPVC​​:ATM PVCs
    ​​AF_APPLETALK​​:AppleTalk
    ​​AF_BLUETOOTH​​:蓝牙协议

Socket 类型(type)
主要类型包括:
    ​​SOCK_STREAM​​:面向连接的字节流
    ​​SOCK_DGRAM​​:无连接的数据报
    ​​SOCK_SEQPACKET​​:有序、可靠、基于连接的双向数据报传输
    ​​SOCK_RAW​​:原始网络协议访问
    ​​SOCK_RDM​​:可靠的数据报层(不保证顺序)
    SOCK_PACKET: 是旧版接口(已弃用)


常见协议组合
传输层协议
    ​​TCP 协议​​:
    socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)      - IPPROTO_TCP(6)
    通常 protocol 参数可以设为 0,系统会自动选择 TCP

    ​​UDP 协议​​:
    socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)       - IPPROTO_UDP(17)
    同样,protocol 参数可以设为 0

    ​​SCTP 协议​​:
    socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)
    socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)

网络层协议
​​原始 IP 套接字​​:
    socket(AF_INET, SOCK_RAW, IPPROTO_RAW) - 可以构造完整的 IP 包 IPPROTO_RAW(255)
    socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) - 接收 ICMP 包       IPPROTO_ICMP(1)
    socket(AF_INET, SOCK_RAW, IPPROTO_IGMP) - 接收 IGMP 包       IPPROTO_IGMP(2)
    socket(AF_INET, SOCK_RAW, IPPROTO_IPIP) - IPIP(网络层)     IPPROTO_IPIP(4)
    socket(AF_INET, SOCK_RAW, IPPROTO_GRE)  - GRE(网络层)      IPPROTO_GRE(47)
接收的数据包含完成的IP包头;默认发送无需自行拼接IP包头,如果设置了setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int)) 则发包时需要自行拼接包头;
网络层数据不存在沾包情况,因为网络数据有明确的大小,每个数据包有编号,当数据超过MTU时,内核自动分包;接收端自行重组,应用程序收到的是原始IP头和数据

​​IPv6 原始套接字​​:
    socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)

数据链路层协议
​​原始以太网帧​​:
    socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) - 接收所有协议   ETH_P_ALL(0x0003)
    socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)) - 仅接收 IP 包   ETH_P_IP(0x0800)
    socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)) - 接收 ARP 包   ETH_P_ARP(0x0806)
    socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL)) - 旧版链路层套接字(已弃用)
接收数据时包含完整的以太网头+对应协议包头和数据;发送时需要自行拼接以太网包头;使用时注意需要用htons(ETH_P_*)

​​数据链路层数据报​​:
    socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))


其他协议
​​Unix 域套接字​​:
    socket(AF_UNIX, SOCK_STREAM, 0) - 流式 Unix 域套接字
    socket(AF_UNIX, SOCK_DGRAM, 0) - 数据报 Unix 域套接字

​​Netlink 套接字​​:
    socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) - 路由信息
    socket(AF_NETLINK, SOCK_RAW, NETLINK_USERSOCK) - 保留给用户程序

​​蓝牙协议​​:
    socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
    socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)

SOCK_STREAM 和 SOCK_DGRAM 的使用范围
关于 SOCK_STREAM 和 SOCK_DGRAM 是否只能用于传输层套接字的问题:

​​主要用途​​:
    SOCK_STREAM 和 SOCK_DGRAM ​​主要​​用于传输层协议(TCP/UDP/SCTP等)
​​其他用途​​:
    它们也可以用于​​非传输层​​的套接字,例如:Unix 域套接字(AF_UNIX)支持这两种类型

    某些特殊协议也可能支持这些类型
    ​​典型组合​​:
        在 AF_INET/AF_INET6 域中:
        SOCK_STREAM 几乎总是与 TCP 协议关联
        SOCK_DGRAM 几乎总是与 UDP 协议关联
        在 AF_UNIX 域中:
        SOCK_STREAM 提供可靠的字节流
        SOCK_DGRAM 提供保留消息边界的数据报服务
    ​例外情况​​:
        某些非传输层协议可能使用这些类型,但这是特例而非惯例
        例如,AF_PACKET 理论上可以使用 SOCK_DGRAM,但实际中更常用 SOCK_RAW

因此,虽然 SOCK_STREAM 和 SOCK_DGRAM ​​主要​​用于传输层套接字,但它们并非​​只能​​用于传输层,在某些其他协议族中也有应用。
 


Socket 选项通过 setsockopt 和 getsockopt 系统调用控制,参数结构为:

    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
    int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

其中:
    level:选项级别(协议层)
    optname:具体选项名称
    optval:选项值指针
    optlen:选项值长度

level的值:
    通用套接字选项 (SOL_SOCKET)
    IP协议选项 (IPPROTO_IP)
    TCP协议选项 (IPPROTO_TCP)
    IPv6协议选项 (IPPROTO_IPV6)
    数据链路层选项 (SOL_PACKET)


以下按协议层级分类说明常用选项:

🔧 一、通用套接字选项 (SOL_SOCKET)
适用于所有套接字类型的通用选项

📌 setsockopt 选项
选项名            值类型           含义                                 使用场景
SO_REUSEADDR    int              允许重用本地地址(TIME_WAIT状态)      服务器快速重启
SO_REUSEPORT    int              允许多个进程绑定相同IP+端口          多进程服务器负载均衡
SO_KEEPALIVE    int              开启TCP保活机制                     检测死连接(需结合TCP_KEEP*选项)
SO_LINGER        struct linger 关闭时处理未发送数据                  控制关闭行为:{ l_onoff=1, l_linger=超时秒数 }
SO_SNDBUF        int              设置发送缓冲区大小                  高吞吐量传输优化
SO_RCVBUF        int              设置接收缓冲区大小                  高吞吐量传输优化
SO_BINDTODEVICE    char[]          绑定到指定网络接口                  多网卡服务器流量隔离
SO_BROADCAST    int              允许发送广播数据                      UDP广播应用 需设置 SO_BROADCAST 才能发送广播数据
SO_DONTROUTE    int              不经过路由表直接发送                  局域网调试
SO_OOBINLINE    int              将带外数据放入普通数据流               处理紧急数据
SO_TIMESTAMP    int              接收数据时添加时间戳                  网络延迟测量
SO_ERROR        int              获取并清除套接字错误状态               异步I/O错误处理
SO_RCVTIMEO        struct timeval 接收超时时间    阻塞式套接字的接收超时    设置 recv() 的最大等待时间
SO_SNDTIMEO        struct timeval 发送超时时间    阻塞式套接字的发送超时    设置 send() 的最大等待时间


SO_ATTACH_FILTER        绑定 BPF 过滤器            过滤网络数据包          struct sock_fprog    用于 AF_PACKET 套接字过滤数据包
SO_ATTACH_BPF            绑定 BPF 程序            高级数据包处理          struct bpf_program    用于 eBPF 程序绑定
SO_ATTACH_REUSEPORT_CB    绑定到 SO_REUSEPORT        多进程共享端口          int    仅用于 SO_REUSEPORT 的扩展
SO_DETACH_REUSEPORT_CB    解除 SO_REUSEPORT绑定    多进程共享端口          int    与 SO_ATTACH_REUSEPORT_CB 配合使用
SO_PASSCRED                获取进程凭证             传递进程信息          int    用于 AF_UNIX 套接字获取发送方的 UID、PID 等信息
SO_PEERNAME                获取对端地址             获取连接的对端地址       struct sockaddr    仅用于已连接的套接字(如 TCP)
SO_PEERSEC                获取对端安全上下文         获取对端的安全信息        char*    用于 SELinux 等安全模块
SO_RCVBUFFORCE            强制设置接收缓冲区         超过系统限制的缓冲区    int    需 CAP_NET_ADMIN 权限
SO_SNDBUFFORCE            强制设置发送缓冲区         超过系统限制的缓冲区    int    需 CAP_NET_ADMIN 权限
SO_RCVNORUSH            接收时不触发 SIGIO         控制信号触发           int    用于 SOCK_DGRAM 套接字
SO_SNDNORUSH            发送时不触发 SIGIO         控制信号触发           int    用于 SOCK_DGRAM 套接字
SO_NO_CHECK                禁用校验和                 用于原始套接字           int    仅用于 SOCK_RAW 套接字,禁用 IP 校验和


🔍 getsockopt 选项
选项名            值类型           含义
SO_TYPE            int              获取套接字类型 (e.g. SOCK_STREAM)
SO_ERROR        int              获取套接字错误码
SO_ACCEPTCONN   int              检测是否监听套接字
SO_SNDBUF        int              获取发送缓冲区大小
SO_RCVBUF        int              获取接收缓冲区大小
SO_SNDLOWAT        int              获取发送低水位标记
SO_RCVLOWAT        int              获取接收低水位标记
SO_DOMAIN        int              获取协议域 (e.g. AF_INET)

🌐 二、IP协议选项 (IPPROTO_IP)
适用于IPv4套接字

📌 setsockopt 选项
选项名               值类型           含义                            使用场景
IP_TOS               int              设置服务类型字段 (DSCP/ECN)    QoS流量控制
IP_TTL               int              设置生存时间 (TTL)            控制数据包传播范围
IP_HDRINCL           int              包含IP头部(原始套接字)         手动构造IP包
IP_OPTIONS           uint8_t[]      设置IP选项                    源路由等高级功能
IP_PKTINFO           int              启用报文信息辅助数据             获取目的IP和接口信息
IP_RECVERR           int              接收详细的ICMP错误信息         精准诊断网络问题
IP_MTU_DISCOVER       int              路径MTU发现策略                1:禁用 2:始终分片 3:启用发现(默认)
IP_RECVTTL           int              接收IP头部的TTL字段            网络拓扑分析
IP_MULTICAST_IF       in_addr          设置多播输出接口                 多网卡环境选择多播网卡
IP_MULTICAST_TTL   u_char          设置多播TTL                    控制多播传播范围
IP_MULTICAST_LOOP  u_char          多播数据回环控制                 0:禁用 1:启用(默认)
IP_ADD_MEMBERSHIP  struct ip_mreq 加入多播组                     多播接收
IP_DROP_MEMBERSHIP struct ip_mreq 离开多播组                     多播组管理

🔍 getsockopt 选项
选项名               值类型           含义
IP_TOS               int              获取服务类型字段
IP_TTL               int              获取生存时间
IP_RECVTTL           int              检查TTL接收功能是否开启
IP_PKTINFO           int              检查报文信息功能是否开启
IP_MTU               int              获取路径MTU
IP_MULTICAST_IF       in_addr          获取多播输出接口
IP_MULTICAST_TTL   u_char          获取多播TTL
IP_MULTICAST_LOOP  u_char          获取多播回环设置

⚡ 三、TCP协议选项 (IPPROTO_TCP)
仅适用于TCP流套接字

📌 setsockopt 选项
选项名               值类型            含义                       使用场景
TCP_NODELAY           int               禁用Nagle算法 (1=禁用)       实时性要求高的应用
TCP_MAXSEG           int               设置最大分段大小 (MSS)       优化传输效率
TCP_KEEPIDLE       int               首次保活探测前的空闲时间(秒)    自定义保活检测频率
TCP_KEEPINTVL       int               保活探测间隔(秒)               自定义保活检测频率
TCP_KEEPCNT           int               保活探测次数                   自定义保活检测次数
TCP_QUICKACK       int               启用快速ACK模式 (1=启用)       减少延迟
TCP_CORK           int               开启TCP_CORK (1=开启)      合并小包提高吞吐量
TCP_FASTOPEN       int               启用TCP快速打开 (队列大小)  减少TLS握手延迟
TCP_DEFER_ACCEPT   int               推迟accept直到数据到达(秒)  避免空连接浪费资源
TCP_INFO           struct tcp_info 设置TCP信息参数               高级TCP诊断和控制

🔍 getsockopt 选项
选项名                值类型             含义
TCP_NODELAY            int                获取Nagle算法状态
TCP_MAXSEG            int                获取当前MSS值
TCP_INFO            struct tcp_info    获取详细TCP连接信息
TCP_KEEPIDLE        int                获取保活空闲时间
TCP_KEEPINTVL        int                获取保活探测间隔
TCP_KEEPCNT            int                获取保活探测次数
TCP_SYNCNT            int                获取SYN重试次数

🌍 四、IPv6协议选项 (IPPROTO_IPV6)
适用于IPv6套接字

📌 setsockopt 选项
选项名                值类型               含义                            使用场景
IPV6_V6ONLY            int                  限制只处理IPv6数据 (1=启用)    避免IPv4映射地址问题
IPV6_RECVPKTINFO    int                  接收目的IPv6和接口索引        高级路由选择
IPV6_RECVHOPLIMIT    int                  接收跳数限制字段              网络拓扑分析
IPV6_RECVRTHDR        int                  接收路由头                   源路由支持
IPV6_UNICAST_HOPS    int                  设置单播跳数限制                控制数据包传播范围
IPV6_MULTICAST_IF    int                  设置多播输出接口索引            多网卡环境选择多播网卡
IPV6_MULTICAST_HOPS    int                  设置多播跳数限制               控制多播传播范围
IPV6_MULTICAST_LOOP    int                  设置多播回环 (1=启用)           本地接收自己发送的多播包
IPV6_JOIN_GROUP        struct ipv6_mreq  加入IPv6多播组               多播接收
IPV6_LEAVE_GROUP    struct ipv6_mreq  离开IPv6多播组               多播组管理
IPV6_CHECKSUM        int                  设置原始套接字的校验和偏移    高级网络编程
IPV6_RTHDRDSTOPTS    int                  接收目标选项头               IPv6扩展支持

🔍 getsockopt 选项
选项名                值类型               含义
IPV6_V6ONLY            int                  获取IPv6-only状态
IPV6_RECVPKTINFO    int                  检查PKTINFO接收功能是否开启
IPV6_RECVHOPLIMIT    int                  检查HOPLIMIT接收功能是否开启
IPV6_UNICAST_HOPS    int                  获取单播跳数限制
IPV6_MULTICAST_IF    int                  获取多播输出接口索引
IPV6_MULTICAST_HOPS    int                  获取多播跳数限制
IPV6_MULTICAST_LOOP    int                  获取多播回环设置

📡 五、数据链路层选项 (SOL_PACKET)
适用于原始数据包套接字 (AF_PACKET)

📌 setsockopt 选项
选项名                    值类型                 含义                        使用场景
PACKET_ADD_MEMBERSHIP    struct packet_mreq    加入数据链路层组            接收特定MAC组播或混杂模式
PACKET_DROP_MEMBERSHIP    struct packet_mreq    离开数据链路层组            停止接收特定MAC组播
PACKET_FANOUT            int                    设置数据包分发策略            多线程/多进程数据包处理负载均衡
PACKET_LOSS                int                    设置接受丢包报告 (1=启用)    网络监控工具
PACKET_RECV_OUTPUT        int                    控制输出方向数据包处理        流量控制
PACKET_TIMESTAMP        int                    设置时间戳精度               1=软件时间戳 2=硬件原始时间戳 3=硬件转换时间戳
PACKET_VERSION            int                    设置数据包版本               兼容不同内核版本
PACKET_QDISC_BYPASS        int                    绕过内核队列规则 (1=启用)    高性能网络应用

🔍 getsockopt 选项
选项名                 值类型                     含义
PACKET_HDRLEN        int                        获取数据包头部长度
PACKET_STATISTICS    struct tpacket_stats    获取数据包统计信息
PACKET_VERSION        int                        获取当前数据包版本
PACKET_FANOUT        struct fanout_args        获取分发策略配置


💡 六、高级选项组合策略

🚀 性能优化组合
    // 高吞吐量TCP服务器
    int yes = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
    setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes));
    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));

    int bufsize = 1024 * 1024; // 1MB
    setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
    setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));

📶 网络诊断组合
    // 网络路径诊断
    int true = 1;
    setsockopt(sock, IPPROTO_IP, IP_RECVERR, &true, sizeof(true));
    setsockopt(sock, IPPROTO_IP, IP_RECVTTL, &true, sizeof(true));
    setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &true, sizeof(true));

    // 获取连接信息
    struct tcp_info info;
    socklen_t len = sizeof(info);
    getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, &len);

🛡️ 安全增强组合
    // IPv6服务器安全加固
    int v6only = 1;
    setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only));

    // 限制服务器只接受完整连接
    int defer_accept = 3; // 等待数据3秒
    setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &defer_accept, sizeof(defer_accept));

    // 绑定特定网络接口
    char ifname[] = "eth0";
    setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, sizeof(ifname));

⚠️ 七、关键注意事项
​​缓冲区大小限制​​:
    设置值可能被内核调整为系统限制范围内
    使用getsockopt验证实际设置值

​​选项继承​​:
    accept()返回的套接字继承监听套接字选项
    TCP_NODELAY等选项需单独设置

​​平台差异​​:
    #if defined(__linux__)
    // Linux特有选项
    setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, ...);
    #elif defined(__APPLE__)
    // macOS特有选项
    setsockopt(sock, IPPROTO_TCP, TCP_KEEPALIVE, ...);
    #endif

​​权限要求​​:
    原始套接字选项(PACKET_*)需要CAP_NET_RAW能力
    网络接口绑定需要特权

​​生效时机​​:
    部分选项需在特定状态前设置(如bind/listen前)

fcntl 函数基础:

fcntl 的调用格式为:
    int fcntl(int fd, int cmd, ...);

cmd 是操作码,arg 是参数(根据 cmd 类型不同,参数类型可能为 int、struct flock、struct sigevent 等)。

二、常用参数组合及含义
1. F_GETFL / F_SETFL:获取/设置文件状态标志
    F_GETFL 返回的标志是 O_RDONLY、O_WRONLY、O_RDWR、O_APPEND、O_ASYNC、O_NONBLOCK 等。
    F_SETFL 可以设置 O_APPEND、O_ASYNC、O_NONBLOCK,但不能设置 O_RDONLY、O_WRONLY、O_RDWR(这些标志只能在 open 时设置)。

使用场景:
    设置非阻塞模式(O_NONBLOCK):用于异步 I/O。
    设置异步信号(O_ASYNC):用于 SIGIO 信号通知。
    设置追加模式(O_APPEND):用于文件写入时自动追加数据。
    注意:O_APPEND 仅对文件有效,套接字通常不使用此标志。

示例:
    // 设置非阻塞模式
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    // 获取当前标志
    int flags = fcntl(fd, F_GETFL);

2. F_GETFD / F_SETFD:获取/设置文件描述符标志
    F_GETFD 返回的标志包括:
    FD_CLOEXEC:设置后,exec() 调用时关闭文件描述符。

使用场景:
    在多进程编程中,避免子进程继承父进程的文件描述符。
    注意:FD_CLOEXEC 是 fcntl 的 F_SETFD 操作码的参数,需与 F_SETFD 配合使用。


示例:
    // 设置 FD_CLOEXEC
    fcntl(fd, F_SETFD, FD_CLOEXEC);

    // 获取 FD_CLOEXEC 标志
    int flags = fcntl(fd, F_GETFD);

3. F_GETOWN / F_SETOWN:获取/设置套接字的信号接收者
    用于设置套接字的信号接收者,通常与 O_ASYNC 配合使用。

使用场景:
    在异步 I/O 中,指定哪个进程接收 SIGIO 信号。
    注意:F_SETOWN 设置的是进程 ID,而 F_SETOWN_EX 可设置进程组或线程组。

示例:
    // 设置 SIGIO 信号接收者为当前进程
    fcntl(fd, F_SETOWN, getpid());

    // 获取当前信号接收者
    int pid = fcntl(fd, F_GETOWN);

4. F_GETOWN_EX / F_SETOWN_EX:获取/设置套接字的信号接收者(进程组/线程组)
    F_SETOWN_EX 支持更细粒度的信号接收者设置(进程组、线程组)。
    参数结构体:
    struct f_owner_ex {
        int type;  // F_OWNER_PID(进程 ID)、F_OWNER_PGRP(进程组)、F_OWNER_TGID(线程组)
        pid_t pid; // 进程 ID
    };

使用场景:
    在多线程环境中,设置线程组接收 SIGIO 信号。
    注意:需 CAP_SYS_ADMIN 权限。

示例:
    struct f_owner_ex owner = {F_OWNER_TGID, gettid()};
    fcntl(fd, F_SETOWN_EX, &owner);

5. F_GETLK / F_SETLK / F_SETLKW:文件锁操作
    cmd    参数类型    含义    使用场景    说明
    F_GETLK    struct flock    获取文件锁状态    获取文件锁信息    用于检查文件是否被锁定
    F_SETLK    struct flock    设置文件锁(非阻塞)    非阻塞加锁    无法等待,立即返回
    F_SETLKW    struct flock    设置文件锁(阻塞)    阻塞加锁    会等待直到锁释放
    F_GETLK    struct flock    获取文件锁状态    获取文件锁信息    用于检查文件是否被锁定
    套接字通常不使用文件锁,但某些系统(如 Linux)支持对文件描述符加锁。

使用场景:
    多进程共享文件描述符时,避免并发访问。
    注意:套接字的 fcntl 操作可能不支持文件锁,需确认系统支持。

示例:
    struct flock fl;
    fl.l_type = F_WRLCK;
    fcntl(fd, F_SETLK, &fl); // 非阻塞加锁


6. F_GETLEASE / F_SETLEASE:文件租约(Lease)
    cmd    参数类型    含义    使用场景    说明
    F_GETLEASE    int    获取文件租约类型    获取租约状态    用于文件租约管理
    F_SETLEASE    int    设置文件租约    设置租约类型    仅在支持租约的文件系统中有效
    F_GETLEASE    int    获取租约类型    获取租约状态    用于文件租约管理
    F_SETLEASE    int    设置租约    设置租约类型    仅在支持租约的文件系统中有效
    套接字通常不使用租约,但某些系统(如 Linux)支持。

使用场景:
    文件租约管理(如 F_SETLEASE 设置租约类型)。
    注意:套接字的 fcntl 通常不涉及租约。

示例:
    int lease = fcntl(fd, F_GETLEASE);

7. F_GETSIG / F_SETSIG:获取/设置信号
    cmd    参数类型    含义    使用场景    说明
    F_GETSIG    int    获取当前信号    获取 SIGIO 信号    用于查询当前信号
    F_SETSIG    int    设置信号    设置 SIGIO 信号    用于指定信号类型(如 SIGIO、SIGURG)
    F_GETSIG    int    获取当前信号    获取 SIGIO 信号    用于查询当前信号
    F_SETSIG    int    设置信号    设置 SIGIO 信号    用于指定信号类型(如 SIGIO、SIGURG)
    用于设置套接字的信号类型(如 SIGIO、SIGURG)。

使用场景:
    配合 F_SETFL 的 O_ASYNC 标志,指定信号类型。
    注意:F_SETSIG 仅在 Linux 中支持,其他系统可能不兼容。

示例:
    // 设置 SIGIO 信号
    fcntl(fd, F_SETSIG, SIGIO);

    // 获取当前信号
    int sig = fcntl(fd, F_GETSIG);

8. F_GETOWN / F_SETOWN:获取/设置套接字的信号接收者
    cmd    参数类型    含义    使用场景    示例
    F_GETOWN    int    获取当前信号接收者(进程 ID)    获取 SIGIO 信号的接收者    int pid = fcntl(fd, F_GETOWN);
    F_SETOWN    int    设置信号接收者(进程 ID)    设置 SIGIO 信号的接收者    fcntl(fd, F_SETOWN, pid);
    说明:
    与 F_GETOWN_EX 的区别:
    F_SETOWN 仅支持进程 ID。
    F_SETOWN_EX 支持进程组、线程组。

使用场景:
    在多进程环境中,指定哪个进程接收 SIGIO 信号。
示例:
    // 设置 SIGIO 信号接收者为当前进程
    fcntl(fd, F_SETOWN, getpid());

    // 获取当前信号接收者
    int pid = fcntl(fd, F_GETOWN);


9. F_GETFD / F_SETFD:获取/设置文件描述符标志
    cmd    参数类型    含义    使用场景    示例
    F_GETFD    int    获取文件描述符标志    获取 FD_CLOEXEC    int flags = fcntl(fd, F_GETFD);
    F_SETFD    int    设置文件描述符标志    设置 FD_CLOEXEC    fcntl(fd, F_SETFD, FD_CLOEXEC);
    FD_CLOEXEC:设置后,exec() 调用时关闭文件描述符。

使用场景:
    在多进程编程中,避免子进程继承父进程的文件描述符。
示例:
    // 设置 FD_CLOEXEC
    fcntl(fd, F_SETFD, FD_CLOEXEC);

    // 获取 FD_CLOEXEC 标志
    int flags = fcntl(fd, F_GETFD);

10. F_GETOWN / F_SETOWN:获取/设置套接字的信号接收者
    cmd    参数类型    含义    使用场景    示例
    F_GETOWN    int    获取当前信号接收者(进程 ID)    获取 SIGIO 信号的接收者    int pid = fcntl(fd, F_GETOWN);
    F_SETOWN    int    设置信号接收者(进程 ID)    设置 SIGIO 信号的接收者    fcntl(fd, F_SETOWN, pid);
    说明:
    与 F_GETOWN_EX 的区别:
    F_SETOWN 仅支持进程 ID。
    F_SETOWN_EX 支持进程组、线程组。

使用场景:
    在多进程环境中,指定哪个进程接收 SIGIO 信号。
示例:
    // 设置 SIGIO 信号接收者为当前进程
    fcntl(fd, F_SETOWN, getpid());

    // 获取当前信号接收者
    int pid = fcntl(fd, F_GETOWN);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值