Files
Netralib/src/Netra.cpp

226 lines
6.6 KiB
C++
Raw Normal View History

2025-07-31 14:47:51 +08:00
#include "Netra.hpp"
namespace QCL
{
TcpServer::TcpServer(int port)
: port_(port), running_(false), serverSock_(-1) {}
/**
* @brief stop()
*/
TcpServer::~TcpServer()
{
stop();
}
/**
* @brief
* 1. socketTCP
* 2.
* 3.
* 4. 线acceptThread_
*
* @return truefalse
*/
bool TcpServer::start()
{
// 创建socket
serverSock_ = socket(AF_INET, SOCK_STREAM, 0);
if (serverSock_ < 0)
{
std::cerr << "Socket 创建失败\n";
return false;
}
// 设置socket地址结构
sockaddr_in serverAddr;
std::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port_); // 端口转网络字节序
serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡IP
// 允许端口重用,防止服务器异常关闭后端口被占用
int opt = 1;
setsockopt(serverSock_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// 绑定端口
if (bind(serverSock_, (sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
{
std::cerr << "绑定失败\n";
return false;
}
// 开始监听最大等待连接数为5
if (listen(serverSock_, 5) < 0)
{
std::cerr << "监听失败\n";
return false;
}
// 设置运行标志为true
running_ = true;
// 启动专门接受客户端连接的线程
acceptThread_ = std::thread(&TcpServer::acceptClients, this);
std::cout << "服务器启动,监听端口:" << port_ << std::endl;
return true;
}
/**
* @brief
* 1. false线退
* 2. socket
* 3. socket
* 4. 线退
*/
void TcpServer::stop()
{
running_ = false;
if (serverSock_ >= 0)
{
close(serverSock_);
serverSock_ = -1;
}
{
// 线程安全关闭所有客户端socket
std::lock_guard<std::mutex> lock(clientsMutex_);
for (int sock : clientSockets_)
{
close(sock);
}
clientSockets_.clear();
}
// 等待监听线程退出
if (acceptThread_.joinable())
acceptThread_.join();
// 等待所有客户端处理线程退出
for (auto &t : clientThreads_)
{
if (t.joinable())
t.join();
}
std::cout << "服务器已停止\n";
}
/**
* @brief acceptClients函数循环监听客户端连接请求
* accept成功
* 1. IP和Socket信息
* 2. 线Socket加入clientSockets_列表
* 3. 线handleClient处理该客户端收发
*/
void TcpServer::acceptClients()
{
while (running_)
{
sockaddr_in clientAddr;
socklen_t clientLen = sizeof(clientAddr);
int clientSock = accept(serverSock_, (sockaddr *)&clientAddr, &clientLen);
if (clientSock < 0)
{
if (running_)
std::cerr << "接受连接失败\n";
continue;
}
// 将客户端IP转换成字符串格式打印
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(clientAddr.sin_addr), clientIP, INET_ADDRSTRLEN);
std::cout << "客户端连接IP: " << clientIP << ", Socket: " << clientSock << std::endl;
{
// 加锁保护共享的clientSockets_容器
std::lock_guard<std::mutex> lock(clientsMutex_);
clientSockets_.push_back(clientSock);
}
}
}
/**
* @brief
* @param clientSock socket
* @param message
*/
void TcpServer::sendToClient(int clientSock, const std::string &message)
{
send(clientSock, message.c_str(), message.size(), 0);
}
/**
* @brief
* @param clientSock socket
*
* 线使
*/
2025-08-04 15:01:31 +08:00
char *TcpServer::receiveFromClient(int clientSock, bool flag)
2025-07-31 14:47:51 +08:00
{
char buffer[1024];
std::memset(buffer, 0, sizeof(buffer));
2025-08-04 15:01:31 +08:00
ssize_t bytesReceived = 0;
if (flag)
bytesReceived = recv(clientSock, buffer, sizeof(buffer) - 1, 0);
else
bytesReceived = recv(clientSock, buffer, sizeof(buffer) - 1, MSG_DONTWAIT);
2025-07-31 14:47:51 +08:00
if (bytesReceived <= 0)
{
return nullptr;
}
return strdup(buffer); // 返回动态分配的字符串副本
}
/**
* @brief Socket副本线
* @return socket的vector副本
*/
std::vector<int> TcpServer::getClientSockets()
{
std::lock_guard<std::mutex> lock(clientsMutex_);
return clientSockets_;
}
2025-08-04 15:01:31 +08:00
/**
* @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;
}
2025-07-31 14:47:51 +08:00
// 屏蔽所有信号
void blockAllSignals()
{
// 忽略全部的信号
for (int ii = 1; ii <= 64; ii++)
signal(ii, SIG_IGN);
}
2025-07-17 15:23:35 +08:00
}