C语言winsock下基于select()的socket聊天室仅服务最新客户端问题求助
问题根因与修复方案
核心问题1:错误释放动态链表节点
你代码中search_client(p_list, i)返回的是链表中存储客户端信息的原生指针,你在完成解密逻辑后直接调用free(client_decrypt),转发逻辑中也调用free(client_encrypt),直接把链表中的节点释放了。这会导致之前接入的客户端节点全部变成野指针,链表结构被破坏,仅剩最后接入、还没被触发过读写事件的客户端节点有效,这就是你只能识别到最后一个客户端的根本原因。
额外附带内存泄漏问题:你先调用create_client()申请了内存,随后直接把指针覆盖为search_client的返回值,刚申请的内存既没有被使用也没有被释放,完全浪费。
核心问题2:转发逻辑执行时机错误
你的转发代码放在了if (FD_ISSET(i, &reads))块的最外层,无论当前触发事件的是监听socket还是客户端socket,无论是否读到有效聊天数据,都会执行转发逻辑。当新客户端接入触发监听socket事件时,你没有读取到任何用户数据,pom_buffer和decrypt_size都是上一次处理的残留值,会产生无效转发甚至逻辑异常。
修复方案
- 删除所有对
search_client返回指针的free调用,链表节点的内存仅在客户端断开连接、调用realese_client时统一释放即可。 - 删除无用的
CLIENT *client_decrypt = create_client();和CLIENT *client_encrypt = create_client();语句,直接用指针接收search_client的返回值即可,不需要额外申请内存。 - 将整个转发逻辑代码块移动到客户端可读事件的
else分支内部,放在解密成功、确认ret_msg != SALT_ERROR之后执行,确保只有收到有效用户数据时才触发转发。
内容的提问来源于stack exchange,提问作者cryptoTuke
相关产品推荐
相关产品推荐

