天天看點

socket傳回值為0的問題排查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 >= )
    {
        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

繼續閱讀