PJSIP 支持通過 TCP 傳輸 SIP 消息,相比 UDP 提供了更可靠的傳輸機制。以下是關于在 PJSIP 中使用 TCP 的詳細指南。
1. 創建 TCP 傳輸
基本 TCP 傳輸配置
c
pjsua_transport_config tcp_cfg;
pjsua_transport_config_default(&tcp_cfg);
tcp_cfg.port = 5060; // SIP 標準端口// 創建 TCP 傳輸
pjsua_transport_id tcp_id;
pj_status_t status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &tcp_cfg, &tcp_id);
if (status != PJ_SUCCESS) {// 錯誤處理
}
2. TCP 與 UDP 的區別
特性 | TCP | UDP |
---|---|---|
可靠性 | 可靠,有重傳機制 | 不可靠,可能丟包 |
連接方式 | 面向連接 | 無連接 |
頭部開銷 | 較大 (20字節) | 較小 (8字節) |
適用場景 | 不穩定網絡環境 | 局域網等穩定環境 |
3. 高級 TCP 配置
保持連接活躍
c
tcp_cfg.qos_type = PJ_QOS_TYPE_VOICE;
tcp_cfg.qos_ignore_error = PJ_TRUE;// 啟用 TCP keepalive
tcp_cfg.tcp_keep_alive = PJ_TRUE;
tcp_cfg.tcp_keep_alive_interval = 30; // 秒
tcp_cfg.tcp_keep_alive_idle = 60; // 秒
設置連接超時
c
tcp_cfg.tcp_conn_timeout = 5000; // 5秒連接超時
4. TCP TLS 配置 (安全傳輸)
c
pjsua_transport_config tls_cfg;
pjsua_transport_config_default(&tls_cfg);
tls_cfg.port = 5061; // SIP TLS 標準端口// 配置證書
tls_cfg.tls_setting.ca_list_file = pj_str("/path/to/ca.pem");
tls_cfg.tls_setting.cert_file = pj_str("/path/to/cert.pem");
tls_cfg.tls_setting.privkey_file = pj_str("/path/to/privkey.pem");// 創建 TLS 傳輸
pjsua_transport_id tls_id;
status = pjsua_transport_create(PJSIP_TRANSPORT_TLS, &tls_cfg, &tls_id);
5. 多傳輸配置
可以同時配置 UDP 和 TCP 傳輸:
c
// 創建 UDP 傳輸
pjsua_transport_id udp_id;
pjsua_transport_config udp_cfg;
pjsua_transport_config_default(&udp_cfg);
udp_cfg.port = 5060;
pjsua_transport_create(PJSIP_TRANSPORT_UDP, &udp_cfg, &udp_id);// 創建 TCP 傳輸
pjsua_transport_id tcp_id;
pjsua_transport_config tcp_cfg;
pjsua_transport_config_default(&tcp_cfg);
tcp_cfg.port = 5060;
pjsua_transport_create(PJSIP_TRANSPORT_TCP, &tcp_cfg, &tcp_id);
6. 強制使用 TCP
如果希望強制使用 TCP 而不是 UDP:
c
pjsua_acc_config acc_cfg;
pjsua_acc_config_default(&acc_cfg);// 設置首選傳輸為 TCP
acc_cfg.transport_id = tcp_id;// 或者通過注冊 URI 指定傳輸
acc_cfg.reg_uri = pj_str("sip:domain.com;transport=tcp");
7. TCP NAT 穿越
TCP 的 NAT 穿越通常比 UDP 簡單,但仍需考慮:
c
// 啟用 STUN
pjsua_config cfg;
pjsua_config_default(&cfg);
cfg.stun_srv_cnt = 1;
cfg.stun_srv[0] = pj_str("stun.example.com");// 或使用 ICE
cfg.ice_cfg_use = PJSUA_ICE_CONFIG_USE_CUSTOM;
cfg.ice_cfg.enable_ice = PJ_TRUE;
8. 性能調優
c
// 調整 TCP 緩沖區大小
tcp_cfg.sock_rcvbuf_size = 8192;
tcp_cfg.sock_sndbuf_size = 8192;// 調整最大連接數
tcp_cfg.tcp_max_connections = 1000;
9. 常見問題解決
連接被拒絕
檢查防火墻設置
確認目標服務器監聽 TCP 端口
檢查網絡路由
連接超時
增加連接超時時間
檢查網絡延遲
驗證服務器是否可達
TLS 握手失敗
確保證書路徑正確
檢查證書有效期
驗證證書鏈完整性
10. 調試 TCP 連接
啟用詳細日志:
c
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 5; // 更詳細的日志
log_cfg.level = 5;
TCP 特定日志可以通過 PJLIB 的 socket 日志查看:
c
extern pj_log_func *pj_log_get_log_func();
pj_log_set_level(3);
pj_log_set_log_func(&my_log_func);
通過合理配置 TCP 傳輸,可以在不穩定網絡環境下獲得更可靠的 SIP 通信體驗。對于移動設備或穿越復雜網絡環境的應用,TCP 通常是更好的選擇。