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