RtpServer.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "RtpServer.h"
  2. #include <QTcpSocket>
  3. #include <QNetworkInterface>
  4. #include <QHostAddress>
  5. #include "ThreadManager.h"
  6. #include "ThreadCompareItemManager.h"
  7. RTPServer::RTPServer(QObject *parent)
  8. : QObject(parent), m_tcpServer(nullptr), m_port(8808)
  9. {
  10. }
  11. RTPServer::~RTPServer()
  12. {
  13. if (m_tcpServer)
  14. {
  15. m_tcpServer->close();
  16. delete m_tcpServer;
  17. m_tcpServer = nullptr;
  18. }
  19. }
  20. /**
  21. * @brief 启动RTP服务
  22. * @param port 监听端口
  23. * @return 成功返回true,失败返回false
  24. */
  25. bool RTPServer::thread_task(int port)
  26. {
  27. m_logger = spdlog::get("RTPServer");
  28. if (!m_logger)
  29. {
  30. fmt::print("RTPServer: Failed to get logger instance.\n");
  31. return false;
  32. }
  33. SPDLOG_LOGGER_INFO(m_logger, "♫ 开启 RTPServer 服务线程");
  34. if(m_tcpServer == nullptr)
  35. {
  36. m_tcpServer = new QTcpServer(this);
  37. }
  38. m_port = port;
  39. if(!m_tcpServer->listen(QHostAddress::Any, m_port))
  40. {
  41. SPDLOG_LOGGER_ERROR(m_logger, "Failed to start RTP server on port {}", m_port);
  42. SPDLOG_LOGGER_ERROR(m_logger, "错误信息: {}", m_tcpServer->errorString().toStdString());
  43. return false;
  44. }
  45. /* 查找到出口IP */
  46. m_localIP = "192.1.2.118";
  47. /* 开启事件循环 */
  48. connect(m_tcpServer, &QTcpServer::newConnection, this, &RTPServer::do_newConnection);
  49. connect(m_tcpServer, &QTcpServer::acceptError, this, &RTPServer::do_error);
  50. m_isStoped.store(false);
  51. m_eventLoop.exec();
  52. m_isStoped.store(true);
  53. SPDLOG_LOGGER_INFO(m_logger, "♫ RTPServer 线程结束运行");
  54. return true;
  55. }
  56. /* 停止线程 */
  57. void RTPServer::stopThreadBlock()
  58. {
  59. if(m_eventLoop.isRunning())
  60. {
  61. m_eventLoop.quit();
  62. }
  63. while(!m_isStoped.load())
  64. {
  65. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  66. }
  67. }
  68. /* 处理新连接 */
  69. void RTPServer::do_newConnection()
  70. {
  71. QTcpSocket* clientSocket = m_tcpServer->nextPendingConnection();
  72. if (clientSocket == nullptr)
  73. {
  74. SPDLOG_LOGGER_ERROR(m_logger, "Failed to get pending connection.");
  75. return;
  76. }
  77. connect(clientSocket, &QTcpSocket::disconnected, this, &RTPServer::do_disconnect);
  78. connect(clientSocket, &QTcpSocket::readyRead, this, &RTPServer::do_receiveMessage);
  79. SPDLOG_LOGGER_INFO(m_logger, "新的客户端连接: {}", clientSocket->peerAddress().toString().toStdString());
  80. m_listClients.append(clientSocket); // 添加到客户端列表中
  81. }
  82. /* 监听服务错误 */
  83. void RTPServer::do_error(QAbstractSocket::SocketError socketError)
  84. {
  85. SPDLOG_LOGGER_ERROR(m_logger, "RTP Server error: {}, {}", static_cast<int>(socketError), m_tcpServer->errorString().toStdString());
  86. }
  87. /* 断开连接 */
  88. void RTPServer::do_disconnect()
  89. {
  90. QTcpSocket* clientSocket = qobject_cast<QTcpSocket*>(sender());
  91. if (clientSocket)
  92. {
  93. SPDLOG_LOGGER_INFO(m_logger, "客户端断开连接: {}", clientSocket->peerAddress().toString().toStdString());
  94. clientSocket->deleteLater();
  95. m_listClients.removeAll(clientSocket);
  96. } else
  97. {
  98. SPDLOG_LOGGER_ERROR(m_logger, "Failed to cast sender to QTcpSocket.");
  99. }
  100. }
  101. /* 接收消息 */
  102. void RTPServer::do_receiveMessage()
  103. {
  104. QTcpSocket* clientSocket = qobject_cast<QTcpSocket*>(sender());
  105. if (clientSocket == nullptr)
  106. {
  107. SPDLOG_LOGGER_ERROR(m_logger, "Failed to cast sender to QTcpSocket.");
  108. return;
  109. }
  110. QString recvIP = clientSocket->peerAddress().toString();
  111. quint16 recvPort = clientSocket->peerPort();
  112. QByteArray data = clientSocket->readAll();
  113. if (data.isEmpty())
  114. {
  115. SPDLOG_LOGGER_WARN(m_logger, "Received empty data from client: {}", recvIP.toStdString());
  116. return;
  117. }
  118. SPDLOG_LOGGER_TRACE(m_logger, "RTPServer从: {}:{} 接收到原始数据: {}, 大小: {}",
  119. recvIP.toStdString(), recvPort, data.toHex().toStdString(), data.size());
  120. // SPDLOG_LOGGER_TRACE(m_logger, "RTPServer从: {}:{} 接收到数据: {}",
  121. // clientSocket->peerAddress().toString().toStdString(), clientSocket->peerPort(),
  122. // QString(data).toStdString());
  123. // return;
  124. if(static_cast<unsigned long>(data.size()) < sizeof(RtpRecvClientInfo_t))
  125. {
  126. SPDLOG_LOGGER_WARN(m_logger, "从客户端接收到的数据大小: {} 低于应有的大小 {}",
  127. data.size(), sizeof(RtpRecvClientInfo_t));
  128. return;
  129. }
  130. /* 处理接收到的数据 */
  131. RtpSendClientInfo_t sendInfo;
  132. RtpRecvClientInfo_t* recvInfo = reinterpret_cast<RtpRecvClientInfo_t*>(data.data());
  133. SPDLOG_LOGGER_DEBUG(m_logger, "客户端信息: ");
  134. SPDLOG_LOGGER_DEBUG(m_logger, " 客户端IP: {}", recvInfo->clientIP);
  135. SPDLOG_LOGGER_DEBUG(m_logger, " 客户端端口: {}", recvInfo->clientPort);
  136. SPDLOG_LOGGER_DEBUG(m_logger, " 对比项ID: {}", recvInfo->compareItemID);
  137. SPDLOG_LOGGER_DEBUG(m_logger, " 对比项通道号: {}", recvInfo->compareItemRoadNum);
  138. SPDLOG_LOGGER_DEBUG(m_logger, " 客户端名称: {}", recvInfo->sessionName);
  139. SPDLOG_LOGGER_DEBUG(m_logger, " 包类型: {}", recvInfo->type);
  140. /* 解析客户端发送的信息 */
  141. sendInfo.clientIP = recvInfo->clientIP;
  142. sendInfo.clientPort = recvInfo->clientPort;
  143. sendInfo.compareItemID = recvInfo->compareItemID;
  144. sendInfo.compareItemRoadNum = recvInfo->compareItemRoadNum;
  145. /* 根据对比项ID和通道编号查找到使用到的声卡通道编号 */
  146. SoundCardRoadInfo_t roadInfo = CompareItemManager.getSoundCardRoadInfo(sendInfo.compareItemID, sendInfo.compareItemRoadNum);
  147. if(roadInfo.nSoundCardNum < 0 || roadInfo.roadInfo.nRoadNum < 0)
  148. {
  149. SPDLOG_LOGGER_ERROR(m_logger, "无法获取对比项 {} 通道 {} 的声卡信息",
  150. sendInfo.compareItemID, sendInfo.compareItemRoadNum);
  151. return;
  152. }
  153. sendInfo.SoundCardNum = roadInfo.nSoundCardNum;
  154. sendInfo.SoundCardRoadNum = roadInfo.roadInfo.nRoadNum;
  155. switch(recvInfo->type)
  156. {
  157. case 0: // 登录请求
  158. handleLogin(sendInfo);
  159. break;
  160. case 1: // 心跳请求
  161. handleHeartbeat(sendInfo);
  162. break;
  163. case 2: // 注销请求
  164. handleLogout(sendInfo);
  165. break;
  166. default:
  167. SPDLOG_LOGGER_WARN(m_logger, "来自客户端未知的请求:{}, {}:{}", recvInfo->type, sendInfo.clientIP.toStdString(), sendInfo.clientPort);
  168. break;
  169. }
  170. }
  171. /* 接收到释放端口的信号 */
  172. void RTPServer::do_udpClosed(int soundCardNum, int roadNum, int localPort)
  173. {
  174. SPDLOG_LOGGER_DEBUG(m_logger, "接收到释放本地端口的信号: 声卡编号: {}, 通道编号: {}, 本地端口: {}",
  175. soundCardNum, roadNum, localPort);
  176. for(auto it = m_mapSoundCardRoadPorts.begin(); it != m_mapSoundCardRoadPorts.end(); ++it)
  177. {
  178. if(it.key().nSoundCardNum == soundCardNum && it.key().nRoadNum == roadNum)
  179. {
  180. // SPDLOG_LOGGER_DEBUG(m_logger, "从声卡通道列表中删除: 声卡编号: {}, 通道编号: {}, 本地端口: {}",
  181. // soundCardNum, roadNum, localPort);
  182. m_mapSoundCardRoadPorts.remove(it.key());
  183. break;
  184. }
  185. }
  186. }
  187. /* 处理登录请求 */
  188. void RTPServer::handleLogin(RtpSendClientInfo_t& clientInfo)
  189. {
  190. SPDLOG_LOGGER_TRACE(m_logger, "处理登录请求: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
  191. /* 查找本地可用的UDP端口,这里先使用10010测试 */
  192. clientInfo.localPort = 10010;
  193. clientInfo.localIP = m_localIP;
  194. /* 查找RTP发送线程 */
  195. auto pThread = ThreadMan.getRtpSendThread(clientInfo.SoundCardNum, clientInfo.SoundCardRoadNum);
  196. if(pThread == nullptr)
  197. {
  198. SPDLOG_LOGGER_ERROR(m_logger, "没有找到对应的RTP发送线程,声卡编号: {}, 通道编号: {}",
  199. clientInfo.SoundCardNum, clientInfo.SoundCardRoadNum);
  200. return;
  201. }
  202. /* 设置客户端信息 */
  203. if(!pThread->addUdpSession(clientInfo))
  204. {
  205. return;
  206. }
  207. connect(pThread, &RTPOneRoadThread::signal_udpClosed, this, &RTPServer::do_udpClosed);
  208. /* 将本地端口添加到声卡通道列表中 */
  209. for(auto it = m_mapSoundCardRoadPorts.begin(); it != m_mapSoundCardRoadPorts.end(); ++it)
  210. {
  211. if(it.key().nSoundCardNum == clientInfo.SoundCardNum && it.key().nRoadNum == clientInfo.SoundCardRoadNum)
  212. {
  213. return;
  214. }
  215. }
  216. SoundCardRoadKey_t roadInfo;
  217. roadInfo.nSoundCardNum = clientInfo.SoundCardNum;
  218. roadInfo.nRoadNum = clientInfo.SoundCardRoadNum;
  219. m_mapSoundCardRoadPorts.insert(roadInfo, clientInfo.localPort);
  220. }
  221. /* 处理心跳请求 */
  222. void RTPServer::handleHeartbeat(RtpSendClientInfo_t& clientInfo)
  223. {
  224. SPDLOG_LOGGER_TRACE(m_logger, "处理心跳请求: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
  225. }
  226. /* 处理注销请求 */
  227. void RTPServer::handleLogout(RtpSendClientInfo_t& clientInfo)
  228. {
  229. SPDLOG_LOGGER_TRACE(m_logger, "处理注销请求: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
  230. /* 查找RTP发送线程 */
  231. auto pThread = ThreadMan.getRtpSendThread(clientInfo.SoundCardNum, clientInfo.SoundCardRoadNum);
  232. if(pThread == nullptr)
  233. {
  234. SPDLOG_LOGGER_ERROR(m_logger, "没有找到对应的RTP发送线程,声卡编号: {}, 通道编号: {}",
  235. clientInfo.SoundCardNum, clientInfo.SoundCardRoadNum);
  236. return;
  237. }
  238. /* 删除UDP会话 */
  239. if(!pThread->removeUdpSession(clientInfo.clientIP, clientInfo.clientPort))
  240. {
  241. SPDLOG_LOGGER_ERROR(m_logger, "删除UDP会话失败: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
  242. return;
  243. }
  244. }
  245. /* 查找本地出口IP,适用于单个出口IP,如果电脑上有多个网口,需要手动指定IP */
  246. QString RTPServer::findLocalIP()
  247. {
  248. QString localIP;
  249. QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
  250. for (const QHostAddress& address : addresses)
  251. {
  252. if (address.protocol() == QAbstractSocket::IPv4Protocol && !address.isLoopback())
  253. {
  254. if(address == QHostAddress::AnyIPv4)
  255. {
  256. continue; // 跳过
  257. }
  258. localIP = address.toString();
  259. SPDLOG_LOGGER_INFO(m_logger, "找到本地出口IP: {}", localIP.toStdString());
  260. return localIP;
  261. }
  262. }
  263. SPDLOG_LOGGER_ERROR(m_logger, "未找到有效的本地出口IP");
  264. return localIP;
  265. }