From a6e82799f5077df339e65ad4c6ab92e5c87bc063 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 9 Apr 2022 10:26:15 +0800 Subject: [PATCH] =?UTF-8?q?openRtpServer=E6=8E=A5=E5=8F=A3=E6=96=B0?= =?UTF-8?q?=E5=A2=9Ere=5Fuse=5Fport=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postman/ZLMediaKit.postman_collection.json | 5 +++++ server/WebApi.cpp | 2 +- src/Rtp/RtpServer.cpp | 8 ++++---- src/Rtp/RtpServer.h | 3 ++- src/Rtsp/Rtsp.cpp | 14 +++++--------- src/Rtsp/Rtsp.h | 2 +- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/postman/ZLMediaKit.postman_collection.json b/postman/ZLMediaKit.postman_collection.json index 035870b6..6d5d42ee 100644 --- a/postman/ZLMediaKit.postman_collection.json +++ b/postman/ZLMediaKit.postman_collection.json @@ -1289,6 +1289,11 @@ "key": "stream_id", "value": "test", "description": "该端口绑定的流id\n" + }, + { + "key": "re_use_port", + "value": "0", + "description": "是否重用端口,默认为0,非必选参数" } ] } diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 16478ca1..c725a1e0 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -1056,7 +1056,7 @@ void installWebApi() { } RtpServer::Ptr server = std::make_shared(); - server->start(allArgs["port"], stream_id, allArgs["enable_tcp"].as(), "0.0.0.0", false); + server->start(allArgs["port"], stream_id, allArgs["enable_tcp"].as(), "0.0.0.0", allArgs["re_use_port"].as()); server->setOnDetach([stream_id]() { //设置rtp超时移除事件 lock_guard lck(s_rtpServerMapMtx); diff --git a/src/Rtp/RtpServer.cpp b/src/Rtp/RtpServer.cpp index ea573a16..2963cd25 100644 --- a/src/Rtp/RtpServer.cpp +++ b/src/Rtp/RtpServer.cpp @@ -88,21 +88,21 @@ private: std::shared_ptr _rtcp_addr; }; -void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable_tcp, const char *local_ip, bool enable_reuse) { +void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable_tcp, const char *local_ip, bool re_use_port) { //创建udp服务器 Socket::Ptr rtp_socket = Socket::createSocket(nullptr, true); Socket::Ptr rtcp_socket = Socket::createSocket(nullptr, true); if (local_port == 0) { //随机端口,rtp端口采用偶数 auto pair = std::make_pair(rtp_socket, rtcp_socket); - makeSockPair(pair, local_ip); + makeSockPair(pair, local_ip, re_use_port); //取偶数端口 rtp_socket = pair.first; rtcp_socket = pair.second; - } else if (!rtp_socket->bindUdpSock(local_port, local_ip, enable_reuse)) { + } else if (!rtp_socket->bindUdpSock(local_port, local_ip, re_use_port)) { //用户指定端口 throw std::runtime_error(StrPrinter << "创建rtp端口 " << local_ip << ":" << local_port << " 失败:" << get_uv_errmsg(true)); - } else if(!rtcp_socket->bindUdpSock(rtp_socket->get_local_port() + 1, local_ip, enable_reuse)) { + } else if (!rtcp_socket->bindUdpSock(rtp_socket->get_local_port() + 1, local_ip, re_use_port)) { // rtcp端口 throw std::runtime_error(StrPrinter << "创建rtcp端口 " << local_ip << ":" << local_port << " 失败:" << get_uv_errmsg(true)); } diff --git a/src/Rtp/RtpServer.h b/src/Rtp/RtpServer.h index b9c71533..77c0c4e7 100644 --- a/src/Rtp/RtpServer.h +++ b/src/Rtp/RtpServer.h @@ -37,8 +37,9 @@ public: * @param stream_id 流id,置空则使用ssrc * @param enable_tcp 是否启用tcp服务器 * @param local_ip 绑定的本地网卡ip + * @param re_use_port 是否设置socket为re_use属性 */ - void start(uint16_t local_port, const std::string &stream_id = "", bool enable_tcp = true, const char *local_ip = "0.0.0.0",bool enable_reuse = true); + void start(uint16_t local_port, const std::string &stream_id = "", bool enable_tcp = true, const char *local_ip = "0.0.0.0", bool re_use_port = true); /** * 获取绑定的本地端口 diff --git a/src/Rtsp/Rtsp.cpp b/src/Rtsp/Rtsp.cpp index f7235042..188ec14e 100644 --- a/src/Rtsp/Rtsp.cpp +++ b/src/Rtsp/Rtsp.cpp @@ -384,7 +384,7 @@ public: return *instance; } - void bindUdpSock(std::pair &pair, const string &local_ip) { + void bindUdpSock(std::pair &pair, const string &local_ip, bool re_use_port) { auto &sock0 = pair.first; auto &sock1 = pair.second; auto sock_pair = getPortPair(); @@ -392,12 +392,12 @@ public: throw runtime_error("none reserved udp port in pool"); } - if (!sock0->bindUdpSock(2 * *sock_pair, local_ip.data(), false)) { + if (!sock0->bindUdpSock(2 * *sock_pair, local_ip.data(), re_use_port)) { //分配端口失败 throw runtime_error("open udp socket[0] failed"); } - if (!sock1->bindUdpSock(2 * *sock_pair + 1, local_ip.data(), false)) { + if (!sock1->bindUdpSock(2 * *sock_pair + 1, local_ip.data(), re_use_port)) { //分配端口失败 throw runtime_error("open udp socket[1] failed"); } @@ -445,18 +445,14 @@ private: deque _port_pair_pool; }; -static void makeSockPair_l(std::pair &pair, const string &local_ip) { - PortManager::Instance().bindUdpSock(pair, local_ip); -} - -void makeSockPair(std::pair &pair, const string &local_ip) { +void makeSockPair(std::pair &pair, const string &local_ip, bool re_use_port) { //全局互斥锁保护,防止端口重复分配 static recursive_mutex s_mtx; lock_guard lck(s_mtx); int try_count = 0; while (true) { try { - makeSockPair_l(pair, local_ip); + PortManager::Instance().bindUdpSock(pair, local_ip, re_use_port); break; } catch (exception &ex) { if (++try_count == 3) { diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index ca9c00be..8743add0 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -378,7 +378,7 @@ private: //创建rtp over tcp4个字节的头 toolkit::Buffer::Ptr makeRtpOverTcpPrefix(uint16_t size, uint8_t interleaved); //创建rtp-rtcp端口对 -void makeSockPair(std::pair &pair, const std::string &local_ip); +void makeSockPair(std::pair &pair, const std::string &local_ip, bool re_use_port = false); //十六进制方式打印ssrc std::string printSSRC(uint32_t ui32Ssrc);