本文档由
ccsocket.h/ccsocket.c源码自动生成。 描述ccsocket库的全部公开 ABI(Application Binary Interface),包括类型、常量、枚举、宏与导出函数。
| 宏 / typedef | 值 (Unix) | 值 (Windows) | 说明 |
|---|---|---|---|
ccsocket_t |
int |
intptr_t |
套接字句柄类型 |
INVALID_SOCKET |
(~0) |
系统定义 | 无效套接字常量 |
cciovec_buf_t |
void* |
char* |
IO 向量缓冲区指针 |
cciovec_len_t |
size_t |
uint32_t |
IO 向量长度类型 |
#define MAX_ADDRLEN 255
#define MAX_ERRORLEN 255typedef struct ccsocket_iovec {
#if _WIN32 // Windows: len 在前
cciovec_len_t len;
cciovec_buf_t buf;
#else // Unix: buf 在前
cciovec_buf_t buf;
cciovec_len_t len;
#endif
} ccsocket_iovec_t;
⚠️ 跨平台时字段顺序不同,不可将原始结构跨平台序列化。
ccsocket_init_iov(iov, count) // 清零 iov 数组
ccsocket_get_iov_len(iov, idx) // 读取长度
ccsocket_set_iov_len(iov, idx, slen) // 设置长度
ccsocket_get_iov_buf(iov, idx) // 读取缓冲区指针
ccsocket_set_iov_buf(iov, idx, sbuf) // 设置缓冲区指针typedef enum {
CC_NOFLAG = 0, // 无特殊标志
CC_CLOEXEC = 1, // close-on-exec
CC_NONBLOCK = 2, // 非阻塞
} ccsocket_flags_t;标志可按位组合:CC_CLOEXEC | CC_NONBLOCK 等价于 3。
typedef enum {
CC_OPCODE_ERROR = -1, // 不可恢复错误,需关闭套接字
CC_OPCODE_OK = 0, // 操作成功
CC_OPCODE_WAIT = 1, // 需等待(非阻塞模式下缓冲区空/满)
CC_OPCODE_WANT_REVENT = 2, // 期望可读事件
CC_OPCODE_WANT_WEVENT = 3, // 期望可写事件
} ccsocket_stcode_t;typedef enum {
CC_FAMILY_INVALID = -1, // 无效 / 未知
CC_UNIX = 0, // AF_UNIX Unix 域套接字
CC_INET4 = 1, // AF_INET IPv4
CC_INET6 = 2, // AF_INET6 IPv6
} ccsocket_family_t;typedef enum {
CC_PROTOCOL_INVALID = -1, // 无效协议
CC_TCP = 1, // SOCK_STREAM + IPPROTO_TCP
CC_UDP = 2, // SOCK_DGRAM + IPPROTO_UDP
CC_ICMP = 3, // SOCK_RAW + IPPROTO_ICMP (IPv6 → IPPROTO_ICMPV6)
} ccsocket_protocol_t;typedef enum {
CC_CONNERROR = -1, // 连接失败
CC_CONNECTED = 0, // 已连接
CC_CONNECTING = 1, // 连接中(非阻塞模式)
} ccsocket_conn_state_t;typedef enum {
CC_SENDERROR = -1, // 不可恢复错误
CC_SENDALL = 0, // 文件发送完毕
CC_SENDWAIT = 1, // 发送缓冲区满,需等待
} ccsocket_sendf_state_t;typedef struct ccaddrinfo {
char address[65]; // 点分/冒号分隔 IP 字符串
ccsocket_family_t af; // 地址族
struct ccaddrinfo *next; // 下一节点
} ccaddrinfo_t;这些宏是对底层 ABI 函数的包装,用户在头文件可见。
// 创建套接字
#define ccsocket(domain, protocol) \
ccsocket2((domain), (protocol), CC_NOFLAG)
#define ccsocket1(domain, protocol, flags) \
ccsocket2((domain), (protocol), (ccsocket_flags_t)(flags))
// 接受连接
#define ccsocket_accept(s, flags) \
ccsocket_accept2((s), NULL, NULL, (ccsocket_flags_t)(flags))
#define ccsocket_accept1(s, paddr, pport, flags) \
ccsocket_accept2((s), (paddr), (pport), (ccsocket_flags_t)(flags))
// socketpair
#define ccsocketpair(fds, flags) \
ccsocketpair1((fds), (ccsocket_flags_t)(flags))
// 发送
#define ccsocket_send(s, buf, bsize, wsizep) \
ccsocket_send1((s), (buf), (bsize), (wsizep), 0)
#define ccsocket_sendv(s, iov, iovcnt, wsizep) \
ccsocket_sendv1((s), (iov), (iovcnt), (wsizep), 0)int ccsocket_close(ccsocket_t s);- 说明:关闭套接字。
- 返回值:0 成功,非 0 失败。
ccsocket_t ccsocket2(ccsocket_family_t domain, ccsocket_protocol_t proto, ccsocket_flags_t flags);- 说明:创建套接字(底层 ABI)。
- 参数:
domain:CC_UNIX/CC_INET4/CC_INET6proto:CC_TCP/CC_UDP/CC_ICMPflags:CC_NOFLAG/CC_CLOEXEC/CC_NONBLOCK
- IPv6 ICMP:
domain=CC_INET6+proto=CC_ICMP时使用IPPROTO_ICMPV6(58)替代IPPROTO_ICMP(1),系统未定义该常量时降级为-1。 - 返回值:有效套接字句柄,失败返回
INVALID_SOCKET。
bool ccsocketpair1(ccsocket_t sv[2], ccsocket_flags_t flags);- 说明:创建一对已连接的流式套接字(类似
socketpair)。 - 参数:
sv:输出,长度为 2 的套接字数组。flags:套接字标志。
- Windows 实现:通过 TCP 本地回环模拟。
- 返回值:
true成功,false失败。
bool ccsocket_listen(ccsocket_t s, const char *addr, uint16_t port);- 说明:绑定地址并监听(独占模式)。
- 参数:
s:由ccsocket2创建的套接字。addr:IP 地址字符串(如"0.0.0.0"),Unix 域为路径。port:端口号,Unix 域传 0。
- 行为:优先使用
SO_EXCLUSIVEADDRUSE(Windows)或SO_EXCLBIND(Solaris),其他平台降级为SO_REUSEADDR。 - 返回值:
true成功。
bool ccsocket_listen1(ccsocket_t s, const char *addr, uint16_t port);- 说明:绑定地址并监听(负载均衡模式,允许多进程/线程共享端口)。
- 平台支持:Linux 3.9+, DragonFlyBSD 3.6+, FreeBSD 12+, Solaris 11.4+, AIX 7.2.5.0+。
- 错误处理:失败时
errno/WSAGetLastError()保留底层原始错误(如EADDRINUSE),不会被覆盖为EINVAL。 - 返回值:
true成功。
ccsocket_t ccsocket_accept2(ccsocket_t s, OPTIONAL char *addr, OPTIONAL uint16_t *port, ccsocket_flags_t flags);- 说明:从监听套接字接受一个客户端连接(底层 ABI)。
- 参数:
s:监听套接字。addr:可选,输出客户端 IP / Unix 路径,缓冲区 ≥MAX_ADDRLEN。port:可选,输出客户端端口。flags:新套接字的标志。
- 非阻塞行为:无连接且未出错时返回
(ccsocket_t)0(Unix)或0。 - 返回值:新客户端套接字,失败返回
INVALID_SOCKET,需等待返回0。
bool ccsocket_connect(ccsocket_t s, const char *addr, uint16_t port);- 说明:连接到指定地址和端口。
- 参数:
s:由ccsocket2创建的套接字。addr:目标 IP / Unix 路径。port:目标端口。
- 返回值:
true成功。
ccsocket_conn_state_t ccsocket_is_connected(ccsocket_t s);- 说明:查询套接字连接状态。
- 返回值:
CC_CONNECTED/CC_CONNECTING/CC_CONNERROR。
ccsocket_stcode_t ccsocket_send1(ccsocket_t s, const void *buf, size_t bsize, OPTIONAL int *wsize, int flags);- 说明:发送数据(底层 ABI)。
- 返回值:
CC_OPCODE_OK— 发送完成,*wsize为写入字节数。CC_OPCODE_WAIT— 非阻塞模式下发送缓冲区满。CC_OPCODE_ERROR— 不可恢复错误。
ccsocket_stcode_t ccsocket_sendv1(ccsocket_t s, ccsocket_iovec_t *iov, int iovcnt, OPTIONAL int *wsize, int flags);- 说明:发送聚集 IO 向量数据。
- 参数:
iov:IO 向量数组。iovcnt:向量条目数。
- 返回值:同
ccsocket_send1。
ccsocket_stcode_t ccsocket_recv(ccsocket_t s, char *buf, size_t bsize, OPTIONAL int *rsize);- 说明:接收数据到连续缓冲区。
- 返回值:
CC_OPCODE_OK— 接收成功,*rsize为读取字节数。CC_OPCODE_WAIT— 非阻塞模式下无数据可读。CC_OPCODE_ERROR— 不可恢复错误。
ccsocket_stcode_t ccsocket_recv1(ccsocket_t s, ccsocket_iovec_t *iov, int iovcnt, OPTIONAL int *rsize);- 说明:接收数据到 IO 向量数组。
- 返回值:同
ccsocket_recv。
ccsocket_stcode_t ccsocket_peek(ccsocket_t s, char *buf, size_t bsize, OPTIONAL int *rsize);- 说明:窥视套接字接收缓冲区数据(不移除)。
- 返回值:同
ccsocket_recv。
ccsocket_sendf_state_t ccsocket_sendfile(ccsocket_t s, int fd);- 说明:将文件描述符内容发送到套接字。
- 平台行为:
- macOS/FreeBSD/BSD →
sendfile()系统调用(零拷贝)。 - Linux/Solaris →
sendfile()系统调用(零拷贝)。 - AIX →
send_file()系统调用。 - 其他(含 Windows)→
read()+ccsocket_send()回退。
- macOS/FreeBSD/BSD →
- 注意:非一次性调用;需在循环中调用直到返回
CC_SENDALL或错误。 - 返回值:
CC_SENDALL— 文件发送完毕。CC_SENDWAIT— 需等待(发送缓冲区满)。CC_SENDERROR— 不可恢复错误。
bool ccsocket_get_peername(ccsocket_t s, char *addr, uint16_t *port);- 说明:获取对端(远程)地址和端口。
bool ccsocket_get_sockname(ccsocket_t s, char *addr, uint16_t *port);- 说明:获取本端(本地)地址和端口。
ccsocket_family_t ccsocket_get_family(ccsocket_t s);- 说明:返回套接字地址族(
CC_INET4/CC_INET6/CC_UNIX/CC_FAMILY_INVALID)。
ccsocket_family_t ccsocket_get_version(const char *addr);- 说明:解析字符串判断地址族。
- 返回值:
CC_INET4— IPv4 地址(如"1.1.1.1")。CC_INET6— IPv6 地址(如"::1")。CC_UNIX— Unix 域套接字路径(仅在非 Windows 下,通过stat+S_ISSOCK检测)。CC_FAMILY_INVALID—NULL、非 IP 非套接字路径,设errno = EINVAL。
void ccsocket_get_error(ccsocket_t s, char buf[MAX_ERRORLEN]);- 说明:获取最后一个错误的可读描述。
bool ccsocket_set_nodelay(ccsocket_t s, bool on); // TCP_NODELAY (禁用 Nagle)
bool ccsocket_set_keepalive(ccsocket_t s, bool on); // SO_KEEPALIVE
bool ccsocket_enable_accept_defer(ccsocket_t s); // TCP_DEFER_ACCEPT / SO_ACCEPTFILTERbool ccsocket_set_reuseaddr(ccsocket_t s, bool on); // SO_REUSEADDR
bool ccsocket_set_reuseport(ccsocket_t s, bool on); // SO_REUSEPORT (需内核支持)bool ccsocket_set_nonblock(ccsocket_t s, bool on); // 非阻塞模式
bool ccsocket_set_cloexec(ccsocket_t s, bool on); // close-on-exec
bool ccsocket_set_rcvtimeout(ccsocket_t s, int timeout); // SO_RCVTIMEO (毫秒)
bool ccsocket_set_sndtimeout(ccsocket_t s, int timeout); // SO_SNDTIMEO (毫秒)bool ccsocket_getaddrinfo(const char *domain, ccaddrinfo_t **addrlist);- 说明:解析域名,返回去重后的地址链表。
- 参数:
domain:域名或 IP 字符串;为NULL时返回false并设errno = EINVAL。addrlist:输出,地址链表头指针。调用者需用ccsocket_freeaddrinfo释放。
- 返回值:
true成功,false失败(可通过errno或ccsocket_get_error获取原因)。
void ccsocket_freeaddrinfo(ccaddrinfo_t *addrlist);- 说明:释放
ccsocket_getaddrinfo返回的地址链表。
| 函数 | 签名 | 说明 |
|---|---|---|
ccsizeof |
int ccsizeof(const struct sockaddr_storage*) |
根据 ss_family 返回 sockaddr 实际大小 |
ccsocket2addr |
bool ccsocket2addr(const struct sockaddr_storage*, char*, uint16_t*) |
从 sockaddr 提取 IP 和端口 |
ccsocket_wrap_ip_and_port |
bool ccsocket_wrap_ip_and_port(...) |
将 IP 字符串 + 端口填充到 sockaddr |
_ccsocket_set_flags |
int _ccsocket_set_flags(ccsocket_t, ccsocket_flags_t, bool) |
设置/清除套接字标志 |
_ccsocket_get_family |
int _ccsocket_get_family(ccsocket_t, struct sockaddr_storage*) |
获取套接字地址族 |
ccsocket_listen_internal |
bool ccsocket_listen_internal(ccsocket_t, const char*, uint16_t) |
内部 bind + listen |
ccsocket_recv_internal |
ccsocket_stcode_t ccsocket_recv_internal(...) |
内部 recv |
| 功能 | Linux | macOS | FreeBSD | Windows | Solaris | AIX |
|---|---|---|---|---|---|---|
| TCP | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| UDP | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| ICMP | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Unix Domain | ✅ | ✅ | ✅ | ✅1 | ✅ | ✅ |
socketpair |
✅ | ✅ | ✅ | ✅2 | ✅ | ✅ |
sendfile (零拷贝) |
✅ | ✅ | ✅ | ❌3 | ✅ | ✅ |
accept4 |
✅ | ❌4 | ❌4 | ❌ | ❌ | ❌ |
SO_REUSEPORT |
✅ | ✅ | ✅5 | ❌ | ✅ | ✅ |
TCP_DEFER_ACCEPT |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
SO_ACCEPTFILTER |
❌ | ❌ | ✅ | ❌ | ❌ | ❌ |