mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
rtsp/GB28181随机端口,支持端口范围设置
This commit is contained in:
parent
4314006551
commit
b127d8c2a9
@ -254,6 +254,9 @@ dumpDir=
|
|||||||
port=10000
|
port=10000
|
||||||
#rtp超时时间,单位秒
|
#rtp超时时间,单位秒
|
||||||
timeoutSec=15
|
timeoutSec=15
|
||||||
|
#随机端口范围,最少确保36个端口
|
||||||
|
#该范围同时限制rtsp服务器udp端口范围
|
||||||
|
port_range=30000-35000
|
||||||
|
|
||||||
[rtc]
|
[rtc]
|
||||||
#rtc播放推流、播放超时时间
|
#rtc播放推流、播放超时时间
|
||||||
|
@ -82,7 +82,7 @@ const string kWaitAddTrackMS = GENERAL_FIELD"wait_add_track_ms";
|
|||||||
const string kUnreadyFrameCache = GENERAL_FIELD"unready_frame_cache";
|
const string kUnreadyFrameCache = GENERAL_FIELD"unready_frame_cache";
|
||||||
const string kContinuePushMS = GENERAL_FIELD"continue_push_ms";
|
const string kContinuePushMS = GENERAL_FIELD"continue_push_ms";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kFlowThreshold] = 1024;
|
mINI::Instance()[kFlowThreshold] = 1024;
|
||||||
mINI::Instance()[kStreamNoneReaderDelayMS] = 20 * 1000;
|
mINI::Instance()[kStreamNoneReaderDelayMS] = 20 * 1000;
|
||||||
mINI::Instance()[kMaxStreamWaitTimeMS] = 15 * 1000;
|
mINI::Instance()[kMaxStreamWaitTimeMS] = 15 * 1000;
|
||||||
@ -104,33 +104,24 @@ onceToken token([](){
|
|||||||
mINI::Instance()[kWaitAddTrackMS] = 3000;
|
mINI::Instance()[kWaitAddTrackMS] = 3000;
|
||||||
mINI::Instance()[kUnreadyFrameCache] = 100;
|
mINI::Instance()[kUnreadyFrameCache] = 100;
|
||||||
mINI::Instance()[kContinuePushMS] = 15 * 1000;
|
mINI::Instance()[kContinuePushMS] = 15 * 1000;
|
||||||
},nullptr);
|
});
|
||||||
|
|
||||||
}//namespace General
|
}//namespace General
|
||||||
|
|
||||||
////////////HTTP配置///////////
|
////////////HTTP配置///////////
|
||||||
namespace Http {
|
namespace Http {
|
||||||
#define HTTP_FIELD "http."
|
#define HTTP_FIELD "http."
|
||||||
//http 文件发送缓存大小
|
|
||||||
const string kSendBufSize = HTTP_FIELD"sendBufSize";
|
const string kSendBufSize = HTTP_FIELD"sendBufSize";
|
||||||
//http 最大请求字节数
|
|
||||||
const string kMaxReqSize = HTTP_FIELD"maxReqSize";
|
const string kMaxReqSize = HTTP_FIELD"maxReqSize";
|
||||||
//http keep-alive秒数
|
|
||||||
const string kKeepAliveSecond = HTTP_FIELD"keepAliveSecond";
|
const string kKeepAliveSecond = HTTP_FIELD"keepAliveSecond";
|
||||||
//http 字符编码
|
|
||||||
const string kCharSet = HTTP_FIELD"charSet";
|
const string kCharSet = HTTP_FIELD"charSet";
|
||||||
//http 服务器根目录
|
|
||||||
const string kRootPath = HTTP_FIELD"rootPath";
|
const string kRootPath = HTTP_FIELD"rootPath";
|
||||||
//http 服务器虚拟目录
|
|
||||||
const string kVirtualPath = HTTP_FIELD "virtualPath";
|
const string kVirtualPath = HTTP_FIELD "virtualPath";
|
||||||
//http 404错误提示内容
|
|
||||||
const string kNotFound = HTTP_FIELD"notFound";
|
const string kNotFound = HTTP_FIELD"notFound";
|
||||||
//是否显示文件夹菜单
|
|
||||||
const string kDirMenu = HTTP_FIELD"dirMenu";
|
const string kDirMenu = HTTP_FIELD"dirMenu";
|
||||||
|
|
||||||
const string kForbidCacheSuffix = HTTP_FIELD"forbidCacheSuffix";
|
const string kForbidCacheSuffix = HTTP_FIELD"forbidCacheSuffix";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kSendBufSize] = 64 * 1024;
|
mINI::Instance()[kSendBufSize] = 64 * 1024;
|
||||||
mINI::Instance()[kMaxReqSize] = 4 * 10240;
|
mINI::Instance()[kMaxReqSize] = 4 * 10240;
|
||||||
mINI::Instance()[kKeepAliveSecond] = 15;
|
mINI::Instance()[kKeepAliveSecond] = 15;
|
||||||
@ -155,7 +146,7 @@ onceToken token([](){
|
|||||||
"</html>"
|
"</html>"
|
||||||
<< endl;
|
<< endl;
|
||||||
mINI::Instance()[kForbidCacheSuffix] = "";
|
mINI::Instance()[kForbidCacheSuffix] = "";
|
||||||
},nullptr);
|
});
|
||||||
|
|
||||||
}//namespace Http
|
}//namespace Http
|
||||||
|
|
||||||
@ -164,9 +155,9 @@ namespace Shell {
|
|||||||
#define SHELL_FIELD "shell."
|
#define SHELL_FIELD "shell."
|
||||||
const string kMaxReqSize = SHELL_FIELD"maxReqSize";
|
const string kMaxReqSize = SHELL_FIELD"maxReqSize";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kMaxReqSize] = 1024;
|
mINI::Instance()[kMaxReqSize] = 1024;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace Shell
|
} //namespace Shell
|
||||||
|
|
||||||
////////////RTSP服务器配置///////////
|
////////////RTSP服务器配置///////////
|
||||||
@ -177,13 +168,13 @@ const string kHandshakeSecond = RTSP_FIELD"handshakeSecond";
|
|||||||
const string kKeepAliveSecond = RTSP_FIELD"keepAliveSecond";
|
const string kKeepAliveSecond = RTSP_FIELD"keepAliveSecond";
|
||||||
const string kDirectProxy = RTSP_FIELD"directProxy";
|
const string kDirectProxy = RTSP_FIELD"directProxy";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
//默认Md5方式认证
|
//默认Md5方式认证
|
||||||
mINI::Instance()[kAuthBasic] = 0;
|
mINI::Instance()[kAuthBasic] = 0;
|
||||||
mINI::Instance()[kHandshakeSecond] = 15;
|
mINI::Instance()[kHandshakeSecond] = 15;
|
||||||
mINI::Instance()[kKeepAliveSecond] = 15;
|
mINI::Instance()[kKeepAliveSecond] = 15;
|
||||||
mINI::Instance()[kDirectProxy] = 1;
|
mINI::Instance()[kDirectProxy] = 1;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace Rtsp
|
} //namespace Rtsp
|
||||||
|
|
||||||
////////////RTMP服务器配置///////////
|
////////////RTMP服务器配置///////////
|
||||||
@ -193,11 +184,11 @@ const string kModifyStamp = RTMP_FIELD"modifyStamp";
|
|||||||
const string kHandshakeSecond = RTMP_FIELD"handshakeSecond";
|
const string kHandshakeSecond = RTMP_FIELD"handshakeSecond";
|
||||||
const string kKeepAliveSecond = RTMP_FIELD"keepAliveSecond";
|
const string kKeepAliveSecond = RTMP_FIELD"keepAliveSecond";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kModifyStamp] = false;
|
mINI::Instance()[kModifyStamp] = false;
|
||||||
mINI::Instance()[kHandshakeSecond] = 15;
|
mINI::Instance()[kHandshakeSecond] = 15;
|
||||||
mINI::Instance()[kKeepAliveSecond] = 15;
|
mINI::Instance()[kKeepAliveSecond] = 15;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace RTMP
|
} //namespace RTMP
|
||||||
|
|
||||||
|
|
||||||
@ -210,11 +201,11 @@ const string kAudioMtuSize = RTP_FIELD"audioMtuSize";
|
|||||||
//rtp包最大长度限制,单位是KB
|
//rtp包最大长度限制,单位是KB
|
||||||
const string kRtpMaxSize = RTP_FIELD"rtpMaxSize";
|
const string kRtpMaxSize = RTP_FIELD"rtpMaxSize";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kVideoMtuSize] = 1400;
|
mINI::Instance()[kVideoMtuSize] = 1400;
|
||||||
mINI::Instance()[kAudioMtuSize] = 600;
|
mINI::Instance()[kAudioMtuSize] = 600;
|
||||||
mINI::Instance()[kRtpMaxSize] = 10;
|
mINI::Instance()[kRtpMaxSize] = 10;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace Rtsp
|
} //namespace Rtsp
|
||||||
|
|
||||||
////////////组播配置///////////
|
////////////组播配置///////////
|
||||||
@ -227,32 +218,25 @@ const string kAddrMax = MULTI_FIELD"addrMax";
|
|||||||
//组播TTL
|
//组播TTL
|
||||||
const string kUdpTTL = MULTI_FIELD"udpTTL";
|
const string kUdpTTL = MULTI_FIELD"udpTTL";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kAddrMin] = "239.0.0.0";
|
mINI::Instance()[kAddrMin] = "239.0.0.0";
|
||||||
mINI::Instance()[kAddrMax] = "239.255.255.255";
|
mINI::Instance()[kAddrMax] = "239.255.255.255";
|
||||||
mINI::Instance()[kUdpTTL] = 64;
|
mINI::Instance()[kUdpTTL] = 64;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace MultiCast
|
} //namespace MultiCast
|
||||||
|
|
||||||
////////////录像配置///////////
|
////////////录像配置///////////
|
||||||
namespace Record {
|
namespace Record {
|
||||||
#define RECORD_FIELD "record."
|
#define RECORD_FIELD "record."
|
||||||
//查看录像的应用名称
|
|
||||||
const string kAppName = RECORD_FIELD"appName";
|
const string kAppName = RECORD_FIELD"appName";
|
||||||
//每次流化MP4文件的时长,单位毫秒
|
|
||||||
const string kSampleMS = RECORD_FIELD"sampleMS";
|
const string kSampleMS = RECORD_FIELD"sampleMS";
|
||||||
//MP4文件录制大小,默认一个小时
|
|
||||||
const string kFileSecond = RECORD_FIELD"fileSecond";
|
const string kFileSecond = RECORD_FIELD"fileSecond";
|
||||||
//录制文件路径
|
|
||||||
const string kFilePath = RECORD_FIELD"filePath";
|
const string kFilePath = RECORD_FIELD"filePath";
|
||||||
//mp4文件写缓存大小
|
|
||||||
const string kFileBufSize = RECORD_FIELD"fileBufSize";
|
const string kFileBufSize = RECORD_FIELD"fileBufSize";
|
||||||
//mp4录制完成后是否进行二次关键帧索引写入头部
|
|
||||||
const string kFastStart = RECORD_FIELD"fastStart";
|
const string kFastStart = RECORD_FIELD"fastStart";
|
||||||
//mp4文件是否重头循环读取
|
|
||||||
const string kFileRepeat = RECORD_FIELD"fileRepeat";
|
const string kFileRepeat = RECORD_FIELD"fileRepeat";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kAppName] = "record";
|
mINI::Instance()[kAppName] = "record";
|
||||||
mINI::Instance()[kSampleMS] = 500;
|
mINI::Instance()[kSampleMS] = 500;
|
||||||
mINI::Instance()[kFileSecond] = 60*60;
|
mINI::Instance()[kFileSecond] = 60*60;
|
||||||
@ -260,28 +244,21 @@ onceToken token([](){
|
|||||||
mINI::Instance()[kFileBufSize] = 64 * 1024;
|
mINI::Instance()[kFileBufSize] = 64 * 1024;
|
||||||
mINI::Instance()[kFastStart] = false;
|
mINI::Instance()[kFastStart] = false;
|
||||||
mINI::Instance()[kFileRepeat] = false;
|
mINI::Instance()[kFileRepeat] = false;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace Record
|
} //namespace Record
|
||||||
|
|
||||||
////////////HLS相关配置///////////
|
////////////HLS相关配置///////////
|
||||||
namespace Hls {
|
namespace Hls {
|
||||||
#define HLS_FIELD "hls."
|
#define HLS_FIELD "hls."
|
||||||
//HLS切片时长,单位秒
|
|
||||||
const string kSegmentDuration = HLS_FIELD"segDur";
|
const string kSegmentDuration = HLS_FIELD"segDur";
|
||||||
//HLS切片个数
|
|
||||||
const string kSegmentNum = HLS_FIELD"segNum";
|
const string kSegmentNum = HLS_FIELD"segNum";
|
||||||
//HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数
|
|
||||||
const string kSegmentRetain = HLS_FIELD"segRetain";
|
const string kSegmentRetain = HLS_FIELD"segRetain";
|
||||||
//HLS文件写缓存大小
|
|
||||||
const string kFileBufSize = HLS_FIELD"fileBufSize";
|
const string kFileBufSize = HLS_FIELD"fileBufSize";
|
||||||
//录制文件路径
|
|
||||||
const string kFilePath = HLS_FIELD"filePath";
|
const string kFilePath = HLS_FIELD"filePath";
|
||||||
// 是否广播 ts 切片完成通知
|
|
||||||
const string kBroadcastRecordTs = HLS_FIELD"broadcastRecordTs";
|
const string kBroadcastRecordTs = HLS_FIELD"broadcastRecordTs";
|
||||||
//hls直播文件删除延时,单位秒
|
|
||||||
const string kDeleteDelaySec = HLS_FIELD"deleteDelaySec";
|
const string kDeleteDelaySec = HLS_FIELD"deleteDelaySec";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kSegmentDuration] = 2;
|
mINI::Instance()[kSegmentDuration] = 2;
|
||||||
mINI::Instance()[kSegmentNum] = 3;
|
mINI::Instance()[kSegmentNum] = 3;
|
||||||
mINI::Instance()[kSegmentRetain] = 5;
|
mINI::Instance()[kSegmentRetain] = 5;
|
||||||
@ -289,22 +266,22 @@ onceToken token([](){
|
|||||||
mINI::Instance()[kFilePath] = "./www";
|
mINI::Instance()[kFilePath] = "./www";
|
||||||
mINI::Instance()[kBroadcastRecordTs] = false;
|
mINI::Instance()[kBroadcastRecordTs] = false;
|
||||||
mINI::Instance()[kDeleteDelaySec] = 0;
|
mINI::Instance()[kDeleteDelaySec] = 0;
|
||||||
},nullptr);
|
});
|
||||||
} //namespace Hls
|
} //namespace Hls
|
||||||
|
|
||||||
|
|
||||||
////////////Rtp代理相关配置///////////
|
////////////Rtp代理相关配置///////////
|
||||||
namespace RtpProxy {
|
namespace RtpProxy {
|
||||||
#define RTP_PROXY_FIELD "rtp_proxy."
|
#define RTP_PROXY_FIELD "rtp_proxy."
|
||||||
//rtp调试数据保存目录
|
|
||||||
const string kDumpDir = RTP_PROXY_FIELD"dumpDir";
|
const string kDumpDir = RTP_PROXY_FIELD"dumpDir";
|
||||||
//rtp接收超时时间
|
|
||||||
const string kTimeoutSec = RTP_PROXY_FIELD"timeoutSec";
|
const string kTimeoutSec = RTP_PROXY_FIELD"timeoutSec";
|
||||||
|
const string kPortRange = RTP_PROXY_FIELD "port_range";
|
||||||
|
|
||||||
onceToken token([](){
|
static onceToken token([](){
|
||||||
mINI::Instance()[kDumpDir] = "";
|
mINI::Instance()[kDumpDir] = "";
|
||||||
mINI::Instance()[kTimeoutSec] = 15;
|
mINI::Instance()[kTimeoutSec] = 15;
|
||||||
},nullptr);
|
mINI::Instance()[kPortRange] = "30000-35000";
|
||||||
|
});
|
||||||
} //namespace RtpProxy
|
} //namespace RtpProxy
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,6 +313,9 @@ namespace RtpProxy {
|
|||||||
extern const std::string kDumpDir;
|
extern const std::string kDumpDir;
|
||||||
//rtp接收超时时间
|
//rtp接收超时时间
|
||||||
extern const std::string kTimeoutSec;
|
extern const std::string kTimeoutSec;
|
||||||
|
//随机端口范围,最少确保36个端口
|
||||||
|
//该范围同时限制rtsp服务器udp端口范围
|
||||||
|
extern const std::string kPortRange;
|
||||||
} //namespace RtpProxy
|
} //namespace RtpProxy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
* may be found in the AUTHORS file in the root of the source tree.
|
* may be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
#include <cinttypes>
|
||||||
#include "Rtsp.h"
|
#include "Rtsp.h"
|
||||||
#include "Common/Parser.h"
|
#include "Common/Parser.h"
|
||||||
|
|
||||||
@ -364,28 +365,88 @@ bool RtspUrl::setup(bool isSSL, const string &strUrl, const string &strUser, con
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PortManager : public std::enable_shared_from_this<PortManager> {
|
||||||
|
public:
|
||||||
|
PortManager() {
|
||||||
|
static auto func = [](const string &str, int index) {
|
||||||
|
uint16_t port[] = { 30000, 35000 };
|
||||||
|
sscanf(str.data(), "%" SCNu16 "-%" SCNu16, port, port + 1);
|
||||||
|
return port[index];
|
||||||
|
};
|
||||||
|
GET_CONFIG_FUNC(uint16_t, s_min_port, RtpProxy::kPortRange, [](const string &str) { return func(str, 0); });
|
||||||
|
GET_CONFIG_FUNC(uint16_t, s_max_port, RtpProxy::kPortRange, [](const string &str) { return func(str, 1); });
|
||||||
|
assert(s_max_port > s_min_port + 36);
|
||||||
|
setRange((s_min_port + 1) / 2, s_max_port / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PortManager& Instance() {
|
||||||
|
static auto instance = std::make_shared<PortManager>();
|
||||||
|
return *instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindUdpSock(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip) {
|
||||||
|
auto &sock0 = pair.first;
|
||||||
|
auto &sock1 = pair.second;
|
||||||
|
auto sock_pair = getPortPair();
|
||||||
|
if (!sock_pair) {
|
||||||
|
throw runtime_error("none reserved udp port in pool");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sock0->bindUdpSock(2 * *sock_pair, local_ip.data(), false)) {
|
||||||
|
//分配端口失败
|
||||||
|
throw runtime_error("open udp socket[0] failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sock1->bindUdpSock(2 * *sock_pair + 1, local_ip.data(), false)) {
|
||||||
|
//分配端口失败
|
||||||
|
throw runtime_error("open udp socket[1] failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto on_cycle = [sock_pair](Socket::Ptr &, std::shared_ptr<void> &) {};
|
||||||
|
// udp socket没onAccept事件,设置该回调,目的是为了在销毁socket时,回收对象
|
||||||
|
sock0->setOnAccept(on_cycle);
|
||||||
|
sock1->setOnAccept(on_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setRange(uint16_t start_pos, uint16_t end_pos) {
|
||||||
|
lock_guard<recursive_mutex> lck(_pool_mtx);
|
||||||
|
while (start_pos < end_pos) {
|
||||||
|
_port_pair_pool.emplace_back(start_pos++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<uint16_t> getPortPair() {
|
||||||
|
lock_guard<recursive_mutex> lck(_pool_mtx);
|
||||||
|
if (_port_pair_pool.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto pos = _port_pair_pool.front();
|
||||||
|
_port_pair_pool.pop_front();
|
||||||
|
InfoL << "got port from pool:" << 2 * pos << "-" << 2 * pos + 1;
|
||||||
|
|
||||||
|
weak_ptr<PortManager> weak_self = shared_from_this();
|
||||||
|
std::shared_ptr<uint16_t> ret(new uint16_t(pos), [weak_self, pos](uint16_t *ptr) {
|
||||||
|
delete ptr;
|
||||||
|
auto strong_self = weak_self.lock();
|
||||||
|
if (!strong_self) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InfoL << "return port to pool:" << 2 * pos << "-" << 2 * pos + 1;
|
||||||
|
//回收端口号
|
||||||
|
lock_guard<recursive_mutex> lck(strong_self->_pool_mtx);
|
||||||
|
strong_self->_port_pair_pool.emplace_back(pos);
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
recursive_mutex _pool_mtx;
|
||||||
|
deque<uint16_t> _port_pair_pool;
|
||||||
|
};
|
||||||
|
|
||||||
static void makeSockPair_l(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip) {
|
static void makeSockPair_l(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip) {
|
||||||
auto &pSockRtp = pair.first;
|
PortManager::Instance().bindUdpSock(pair, local_ip);
|
||||||
auto &pSockRtcp = pair.second;
|
|
||||||
|
|
||||||
if (!pSockRtp->bindUdpSock(0, local_ip.data())) {
|
|
||||||
//分配端口失败
|
|
||||||
throw runtime_error("open udp socket failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
//是否是偶数
|
|
||||||
bool even_numbers = pSockRtp->get_local_port() % 2 == 0;
|
|
||||||
if (!pSockRtcp->bindUdpSock(pSockRtp->get_local_port() + (even_numbers ? 1 : -1), local_ip.data())) {
|
|
||||||
//分配端口失败
|
|
||||||
throw runtime_error("open udp socket failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!even_numbers) {
|
|
||||||
//如果rtp端口不是偶数,那么与rtcp端口互换,目的是兼容一些要求严格的播放器或服务器
|
|
||||||
Socket::Ptr tmp = pSockRtp;
|
|
||||||
pSockRtp = pSockRtcp;
|
|
||||||
pSockRtcp = tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSockPair(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip) {
|
void makeSockPair(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local_ip) {
|
||||||
@ -397,11 +458,11 @@ void makeSockPair(std::pair<Socket::Ptr, Socket::Ptr> &pair, const string &local
|
|||||||
try {
|
try {
|
||||||
makeSockPair_l(pair, local_ip);
|
makeSockPair_l(pair, local_ip);
|
||||||
break;
|
break;
|
||||||
} catch (...) {
|
} catch (exception &ex) {
|
||||||
if (++try_count == 3) {
|
if (++try_count == 3) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
WarnL << "open udp socket failed, retry: " << try_count;
|
WarnL << "open udp socket failed:" << ex.what() << ", retry: " << try_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user