ZLMediaKit/src/Rtsp/UDPServer.cpp

100 lines
2.8 KiB
C++
Raw Normal View History

2017-10-09 22:11:01 +08:00
/*
2020-04-04 20:30:09 +08:00
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
2017-09-27 16:20:30 +08:00
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
2017-09-27 16:20:30 +08:00
*
2020-04-04 20:30:09 +08:00
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
2017-04-01 16:35:56 +08:00
*/
#include "UDPServer.h"
#include "Util/TimeTicker.h"
#include "Util/onceToken.h"
2018-10-24 17:17:55 +08:00
using namespace toolkit;
using namespace std;
2017-04-25 11:35:41 +08:00
2018-10-24 17:17:55 +08:00
namespace mediakit {
2017-04-01 16:35:56 +08:00
INSTANCE_IMP(UDPServer);
2017-04-01 16:35:56 +08:00
UDPServer::UDPServer() {
}
UDPServer::~UDPServer() {
2020-03-20 11:51:24 +08:00
InfoL;
2017-04-01 16:35:56 +08:00
}
Socket::Ptr UDPServer::getSock(SocketHelper &helper, const char* local_ip, int interleaved, uint16_t local_port) {
lock_guard<mutex> lck(_mtx_udp_sock);
string key = StrPrinter << local_ip << ":" << interleaved << endl;
auto it = _udp_sock_map.find(key);
if (it == _udp_sock_map.end()) {
Socket::Ptr sock = helper.createSocket();
if (!sock->bindUdpSock(local_port, local_ip)) {
2020-03-20 11:51:24 +08:00
//分配失败
return nullptr;
}
2017-04-01 16:35:56 +08:00
sock->setOnErr(bind(&UDPServer::onErr, this, key, placeholders::_1));
sock->setOnRead(bind(&UDPServer::onRecv, this, interleaved, placeholders::_1, placeholders::_2));
_udp_sock_map[key] = sock;
DebugL << local_ip << " " << sock->get_local_port() << " " << interleaved;
return sock;
2020-03-20 11:51:24 +08:00
}
return it->second;
2017-04-01 16:35:56 +08:00
}
void UDPServer::listenPeer(const char* peer_ip, void* obj, const onRecvData &cb) {
lock_guard<mutex> lck(_mtx_on_recv);
auto &ref = _on_recv_map[peer_ip];
ref.emplace(obj, cb);
2017-04-01 16:35:56 +08:00
}
void UDPServer::stopListenPeer(const char* peer_ip, void* obj) {
lock_guard<mutex> lck(_mtx_on_recv);
auto it0 = _on_recv_map.find(peer_ip);
if (it0 == _on_recv_map.end()) {
2020-03-20 11:51:24 +08:00
return;
}
auto &ref = it0->second;
auto it1 = ref.find(obj);
if (it1 != ref.end()) {
ref.erase(it1);
2020-03-20 11:51:24 +08:00
}
if (ref.size() == 0) {
_on_recv_map.erase(it0);
2020-03-20 11:51:24 +08:00
}
2017-04-01 16:35:56 +08:00
}
void UDPServer::onErr(const string &key, const SockException &err) {
2020-03-20 11:51:24 +08:00
WarnL << err.what();
lock_guard<mutex> lck(_mtx_udp_sock);
_udp_sock_map.erase(key);
2017-04-01 16:35:56 +08:00
}
void UDPServer::onRecv(int interleaved, const Buffer::Ptr &buf, struct sockaddr* peer_addr) {
struct sockaddr_in *in = (struct sockaddr_in *) peer_addr;
string peer_ip = SockUtil::inet_ntoa(in->sin_addr);
lock_guard<mutex> lck(_mtx_on_recv);
auto it0 = _on_recv_map.find(peer_ip);
if (it0 == _on_recv_map.end()) {
2020-03-20 11:51:24 +08:00
return;
}
auto &ref = it0->second;
for (auto it1 = ref.begin(); it1 != ref.end(); ++it1) {
auto &func = it1->second;
if (!func(interleaved, buf, peer_addr)) {
it1 = ref.erase(it1);
2020-03-20 11:51:24 +08:00
}
}
if (ref.size() == 0) {
_on_recv_map.erase(it0);
2020-03-20 11:51:24 +08:00
}
2017-04-01 16:35:56 +08:00
}
2018-10-24 17:17:55 +08:00
} /* namespace mediakit */
2017-04-01 16:35:56 +08:00