From 8d311a00b4e6f6730d7a0f0255a1dfac7a3863c5 Mon Sep 17 00:00:00 2001 From: Quella777 <2892744389@qq.com> Date: Mon, 4 Aug 2025 15:01:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Netra.hpp | 10 ++++++++-- src/Netra.cpp | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/Netra.hpp b/include/Netra.hpp index b256c3c..9540779 100644 --- a/include/Netra.hpp +++ b/include/Netra.hpp @@ -1,7 +1,6 @@ #pragma once #include "QCL_Include.hpp" - namespace QCL { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -48,8 +47,15 @@ namespace QCL /** * @brief 从指定客户端接收数据(单次调用) * @param clientSock 客户端Socket描述符 + * @param flag:false 非阻塞模式,true 阻塞模式 */ - char *receiveFromClient(int clientSock); + char *receiveFromClient(int clientSock,bool flag = true); + + /** + * @brief 获取连接客户端的IP和端口 + * @param clientSock 客户端Socket描述符 + */ + char *getClientIPAndPort(int clientSock); /** * @brief 获取当前所有已连接客户端Socket的副本 diff --git a/src/Netra.cpp b/src/Netra.cpp index 19f285f..7188325 100644 --- a/src/Netra.cpp +++ b/src/Netra.cpp @@ -158,18 +158,22 @@ namespace QCL * * 注意:此函数在当前设计中未在线程中使用,仅演示用。 */ - char *TcpServer::receiveFromClient(int clientSock) + char *TcpServer::receiveFromClient(int clientSock, bool flag) { char buffer[1024]; std::memset(buffer, 0, sizeof(buffer)); - ssize_t bytesReceived = recv(clientSock, buffer, sizeof(buffer) - 1, 0); + ssize_t bytesReceived = 0; + + if (flag) + bytesReceived = recv(clientSock, buffer, sizeof(buffer) - 1, 0); + else + bytesReceived = recv(clientSock, buffer, sizeof(buffer) - 1, MSG_DONTWAIT); + if (bytesReceived <= 0) { - std::cerr << "接收数据失败或客户端断开连接\n"; return nullptr; } - return strdup(buffer); // 返回动态分配的字符串副本 } @@ -183,6 +187,35 @@ namespace QCL return clientSockets_; } + /** + * @brief 获取连接客户端的IP和端口 + * @param clientSock 客户端Socket描述符 + */ + char *TcpServer::getClientIPAndPort(int clientSock) + { + struct sockaddr_in addr; + socklen_t addr_size = sizeof(addr); + + // 获取客户端地址信息 + if (getpeername(clientSock, (struct sockaddr *)&addr, &addr_size) == -1) + { + perror("getpeername failed"); + return NULL; + } + + // 分配内存存储结果(格式: "IP:PORT") + char *result = (char *)malloc(INET_ADDRSTRLEN + 10); + if (!result) + return NULL; + + // 转换IP和端口 + char *ip = inet_ntoa(addr.sin_addr); + unsigned short port = ntohs(addr.sin_port); + + snprintf(result, INET_ADDRSTRLEN + 10, "%s:%d", ip, port); + return result; + } + // 屏蔽所有信号 void blockAllSignals() {