socket返回值为0的问题排查

socket返回值为0的问题排查

  • socket返回值为0的问题排查
    • 背景知识:
    • 问题现象
    • 问题原因
    • 问题解决

背景知识:

LTE中,eNB和MME之间通过s1ap协议交流,而s1ap的底层协议为sctp。因此s1链路的建立,要依赖于sctp底层链路的建立。需要配置的sctp参数包括:
本地ip、本地端口号、远端ip、远端端口号、心跳间隔、最大路径重传次数、INIT最大重传次数、输入输出流个数等。

而建立socket是sctp建立连接的先决条件,我们使用的时socket函数创建的套接字:

int socket_id = int socket(int af, int type, int protocol);

问题现象

将配置发送给sctp链路管理模块,触发sctp的建立。但是日志显示,利用socket建立的socket_id为0。
通过在网上查阅了一些文章,发现socket建立的时候,socket_id是0,1,2的基本属于标准输入输出套接字标识。通常用户自己创建的socket不会出现这个问题。

问题原因

socket_id为0,1,2的虽然是给标准输入输出用的,但是如果我们close(0)之后,该socket_id = 0的便处于“空闲”状态。用户利用socket函数创建套接字时,便会讲0分配给新创建的socket。

经过查找close函数使用的地方,最终定位到了一处:
1、该模块上下文初始化时,全被初始化为了0,该上下文结构体如下:

    typedef struct _wireshark_global_contxt_t
    {
        ....
        s32    udp_sock_id;
        ...
    } wireshark_global_context_t;

2、该模块初始化时,会建立初始socket连接
该模块建立socket连接时,只允许建立一个连接,因此为了防止存在多个连接的情况,在调用socket函数创建socket之前,加入了如下判断

    if (wiresahrk_gl_ctx.udp_sock_id >= 0)
    {
        close(wireshark_gl_ctx.udp_sock_id);
        wireshark_gl_ctx.udp_sock_id = INVALID_SOCKET; # INVALID_SOCKET = -1
    }

于是就出现了close(0)的情况。

问题解决

1、上下文初始化时,将udp_sock_id初始化为非法值(-1)
2、close() socket连接的时候,判断条件为>0的情况下close

你可能感兴趣的:(Linux,C)