SCTP一对多模式下如何仅关闭单个连接(C语言实现)
在SCTP一对多模式下关闭单个关联的可行方案
你之前使用sctp_sendmsg配合SCTP_ABORT标志的方式已被弃用,且参数配置错误会导致误关闭所有关联。针对Ubuntu 22.04环境,推荐以下两种可靠方案:
方案一:使用sctp_shutdown优雅关闭指定关联
sctp_shutdown是专门用于关闭单个SCTP关联的API,通过指定关联ID可精准操作,不会影响其他连接:
#include <netinet/sctp.h> // 传入要关闭的关联ID asso_id int ret = sctp_shutdown(clientsockfd, asso_id); if (ret == -1) { perror("sctp_shutdown failed"); // 此处添加错误处理逻辑 }
方案二:发送ABORT信号主动终止指定关联
如果需要主动发送终止信号而非优雅关闭,可通过sendmsg配合控制消息实现,精准指定目标关联:
#include <sys/socket.h> #include <netinet/sctp.h> // 假设已获取目标关联ID asso_id struct msghdr msg = {0}; char cmsg_buf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; struct cmsghdr *cmsg; struct sctp_sndrcvinfo sri = {0}; // 初始化控制消息 msg.msg_control = cmsg_buf; msg.msg_controllen = sizeof(cmsg_buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SENDMSG; cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); // 设置关联ID和ABORT标志 sri.sinfo_assoc_id = asso_id; sri.sinfo_flags = SCTP_ABORT; memcpy(CMSG_DATA(cmsg), &sri, sizeof(sri)); // 发送空消息触发ABORT int ret = sendmsg(clientsockfd, &msg, 0); if (ret == -1) { perror("sendmsg failed"); // 此处添加错误处理逻辑 }
如何获取正确的关联ID
如果不知道目标关联的ID,可通过以下方式获取:
- 调用
sctp_recvmsg接收消息时,从返回的sctp_sndrcvinfo结构体中读取spinfo_assoc_id - 通过目标服务器地址获取关联ID:
sctp_assoc_t get_assoc_id(int sockfd, struct sockaddr *addr, socklen_t addr_len) { sctp_assoc_t asso_id; int ret = sctp_getassocid(sockfd, addr, addr_len, &asso_id); if (ret == -1) { perror("sctp_getassocid failed"); return -1; } return asso_id; }
注意事项
- 编译时需链接SCTP库,添加编译选项
-lsctp - 确保使用Linux内核3.0+版本的SCTP API,Ubuntu 22.04环境完全支持
- 关联关闭后,该关联对应的资源会被释放,后续不可再通过此关联发送消息
内容的提问来源于stack exchange,提问作者sandejai
相关产品推荐
相关产品推荐

