#include "../include/CCSocket.h" #include #ifdef _WIN32 CCSocket CCSocket::Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type) { CCSocket sc{}; this->Socketbit = socket(IPV4orIPV6, Type, TCPorUDP); if (this->Socketbit == INVALID_SOCKET){ return sc; } this->sock = TCPorUDP; this->IPVx = IPV4orIPV6; sc.sock = this->sock; sc.IPVx = this->IPVx; sc.Socketbit = this->Socketbit; return sc; } bool CCSocket::SetSockOpt(CCOpt opt){ if(opt == CCOpt::BROADCAST) { int broadcastPermission = 1; if (setsockopt(this->Socketbit, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcastPermission, sizeof(broadcastPermission)) < 0) { return false; } } return true; } std::vector CCSocket::GetLocalIP(IPVX ipvx,int Number) { std::vector IPList; int result = 0; // 获取主机名 char hostName[NI_MAXHOST]; if (gethostname(hostName, NI_MAXHOST) != 0) { std::cerr << "gethostname failed" << std::endl; WSACleanup(); return {}; } struct addrinfo hints, *info; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; // AF_INET for IPv4 only hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // 获取地址信息 result = getaddrinfo(hostName, NULL, &hints, &info); if (result != 0) { std::cerr << "getaddrinfo failed: " << result << std::endl; return {}; } char ipString[INET6_ADDRSTRLEN] = {0}; // 遍历所有地址信息并打印IPv4地址 for (struct addrinfo* p = info; p != nullptr; p = p->ai_next) { void* addr; // 对于IPv4,使用ipv4_mapping来兼容IPv6地址 if (p->ai_family == ipvx) { struct sockaddr_in* ipv4 = (struct sockaddr_in*)p->ai_addr; addr = &(ipv4->sin_addr); } else { continue; // 跳过非IPv4地址 } // 将地址转换为字符串 inet_ntop(p->ai_family, addr, ipString, sizeof(ipString)); IPList.emplace_back(ipString); // std::cout << "IPv4 address: " << ipString << std::endl; } // 释放地址信息 freeaddrinfo(info); return IPList; } bool CCSocket::Connect(const char* IP, unsigned short Port) { Stop = true; sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(Port); serveraddr.sin_addr.s_addr = inet_addr(IP); int len = sizeof(serveraddr); int i = connect(this->Socketbit,(sockaddr*)&serveraddr,len); if (i == SOCKET_ERROR) { return false; } return true; } bool CCSocket::Bind(const char* IP, unsigned short Port){ memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(Port); server.sin_addr.s_addr = inet_addr(IP); int i = bind(this->Socketbit, (sockaddr*)&server, sizeof(server)); if (i == SOCKET_ERROR) { closesocket(this->Socketbit); return false; } return true; } bool CCSocket::Listen(unsigned short UserNum) { Stop = true; int iLisRet = listen(this->Socketbit, UserNum); if (iLisRet == SOCKET_ERROR) { closesocket(this->Socketbit); return false; } return true; } CCSocket CCSocket::Accept() { CCSocket sc; SOCKADDR_IN serveraddrfrom{}; int Len = sizeof(serveraddrfrom); SOCKET s = accept(this->Socketbit, (SOCKADDR*)&serveraddrfrom, &Len); sc.Socketbit = s; sc.IPVx = this->IPVx; sc.sock = this->sock; sc.client = serveraddrfrom; return sc; } bool CCSocket::Send(const char* str) { int ires = send(this->Socketbit, str, strlen(str), 0); //<2F><>ַȥ if (ires == -1) { return false; } return true; } bool CCSocket::SendByte(const char* str, int len) { int ires = send(this->Socketbit, str, len, 0); //<2F><>ַȥ if (ires == -1) { return false; } return true; } bool CCSocket::UDPSend(const char* str, const char* IP, int Port) { sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(Port); // <20><>Ķ˿ں serverAddr.sin_addr.s_addr = inet_addr(IP); // <20><>ĵַ if (sendto(this->Socketbit, str, strlen(str), 0, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { return false; } else { return true; } } bool CCSocket::UDPSendByte(const char* str,ByteHander len ,const char* IP, int Port) { sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(Port); serverAddr.sin_addr.s_addr = inet_addr(IP); if (sendto(this->Socketbit, str, len, 0, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { return false; } else { return true; } } ByteHander CCSocket::RecvData(char* buffer,ByteHander lens) { int len = recv(this->Socketbit,buffer,lens,0); return len; } ByteHander CCSocket::UDPRecvData(char* buffer, ByteHander lens,CCHostInfo* info) { sockaddr_in A = {}; int clientSize = sizeof(A); int bytesReceived = recvfrom(this->Socketbit, buffer, lens+1, 0,(SOCKADDR*)&A, &clientSize); char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &A.sin_addr, IP, INET_ADDRSTRLEN); info->IPAddress = IP; info->Port = ntohs(A.sin_port); return bytesReceived; } void CCSocket::Close() { Stop = false; closesocket(this->Socketbit); } bool CCSocket::GetDateHead(char* data, ByteHander* size) { int i = sizeof(data); memcpy(size,data,i); if (size!=0) { return true; } return false; } bool CCSocket::GetStrHead(char* data, ByteHander size) { for (int i = 0; i < HanderSize; i++) { data[i] = '\0'; } data[0] = '-'; memcpy(data, &size, sizeof(ByteHander)); if (data[0] == '-') { return false; } return true; } bool CCSocket::Send(const void *__buf, size_t __n, int __flags) { int err = send(Socketbit, (char*)__buf, __n, __flags); if(err == -1) { return false; } return true; } bool CCSocket::SendData(const char* str, sockaddr_in addr_in){ bool F = sendto(this->Socketbit, str, strlen(str), 0, (sockaddr*)&addr_in, sizeof(addr_in)) != SOCKET_ERROR; return F; } bool CCSocket::operator==(CCSocket socket) { if(socket.Socketbit == this->Socketbit) { return true; } return false; } bool CCSocket::operator!=(CCSocket socket) { if(socket.Socketbit != this->Socketbit) { return true; } return false; } CCHostInfo CCSocket::GetClientHost() { CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &client.sin_addr, IP, INET_ADDRSTRLEN); hostInfo.IPAddress = IP; hostInfo.Port = ntohs(client.sin_port); return hostInfo; } CCHostInfo CCSocket::GetLocalHost(){ CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &server.sin_addr, IP, INET_ADDRSTRLEN); hostInfo.IPAddress = IP; hostInfo.Port = ntohs(server.sin_port); return hostInfo; } void CCSocket::SetSocketNonBlocking() { u_long mode = 1; if (ioctlsocket(this->Socketbit, FIONBIO, &mode) == SOCKET_ERROR) { std::cerr << "ioctlsocket failed with error: " << WSAGetLastError() << std::endl; } } bool CCSocket::isDataAvailable() { fd_set readfds; FD_ZERO(&readfds); FD_SET(this->Socketbit, &readfds); timeval timeout = {0, 0}; // Non-blocking check int ret = select(0, &readfds, nullptr, nullptr, &timeout); if (ret == SOCKET_ERROR) { //std::cerr << "select failed with error: " << WSAGetLastError() << std::endl; return false; } return FD_ISSET(this->Socketbit, &readfds); } bool CCSocket::isConnectionAlive() { fd_set fds; FD_ZERO(&fds); FD_SET(Socketbit, &fds); timeval timeout = { 0, 0 }; // 非阻塞模式立即返回 int ret = select(Socketbit + 1, &fds, NULL, &fds, &timeout); if (ret < 0) { // 错误处理 return false; } else if (ret > 0) { if (FD_ISSET(Socketbit, &fds)) { if (FD_ISSET(Socketbit, &fds)) { // 检查异常条件 return false; } } } return true; } #elif __linux__ CCSocket CCSocket::Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type) { CCSocket sc; Socketbit = socket(IPV4orIPV6, Type, TCPorUDP); if(Socketbit == 0) { Socketbit = -1; return sc; } int err = setsockopt(Socketbit, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)); if(err) { Socketbit = -2; return sc; } this->IPVx = IPV4orIPV6; sc.IPVx = this->IPVx; sc.Socketbit = Socketbit; return sc; } bool CCSocket::SetSockOpt(CCOpt opt){ if(opt == CCOpt::BROADCAST) { int broadcastPermission = 1; if (setsockopt(this->Socketbit, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcastPermission, sizeof(broadcastPermission)) < 0) { return false; } } return true; } std::vector CCSocket::GetLocalIP(IPVX ipvx,int Number) { std::vector IPList; struct ifaddrs *ifAddrStruct = nullptr; struct ifaddrs *ifa = nullptr; void *tmpAddrPtr = nullptr; getifaddrs(&ifAddrStruct); char addressBuffer[10][INET_ADDRSTRLEN] = {0}; int d = 0; for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family == ipvx) { // 检查它是否为IPv4 // 获取接口地址 tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer[d++], INET_ADDRSTRLEN); IPList.emplace_back(addressBuffer[d-1]); //std::cout << "IPv4 Address: " << addressBuffer << std::endl; } } if (ifAddrStruct != nullptr) freeifaddrs(ifAddrStruct); return IPList; } bool CCSocket::Connect(const char* IP, unsigned short Port) { Stop = true; struct sockaddr_in address; address.sin_family = IPVx; address.sin_addr.s_addr = inet_addr(IP); address.sin_port = htons(Port); int err = inet_pton(AF_INET, IP, &address.sin_addr); if(err <= 0) { return false; } int erra = connect(Socketbit, (struct sockaddr *)&address, sizeof(address)); if(erra < 0) { return false; } return true; } bool CCSocket::Bind(const char* IP,int Port) { // 设置地址结构 struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = IPVx; server_addr.sin_port = htons(Port); server_addr.sin_addr.s_addr = inet_addr(IP); // 绑定套接字到地址和端口 if (bind(this->Socketbit, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { std::cerr << "Bind failed" << std::endl; return false; } return true; } bool CCSocket::Listen(unsigned short UserNum) { Stop = true; int err = listen(Socketbit, UserNum); if(err < 0) { return false; } return true; } CCSocket CCSocket::Accept() { CCSocket sc; sockaddr_in serveraddrfrom{}; socklen_t Len = sizeof(serveraddrfrom); SOCKET s = accept(this->Socketbit, (struct sockaddr *)&serveraddrfrom, &Len); sc.IPVx = this->IPVx; sc.Socketbit = s; sc.client = serveraddrfrom; return sc; } bool CCSocket::Send(const char* str) { int err = send(Socketbit, str, strlen(str), 0); if(err == -1) { return false; } return true; } bool CCSocket::SendByte(const char* str,int len) { int err = send(Socketbit, str, len, 0); if(err == -1) { return false; } return true; } bool CCSocket::UDPSend(const char* str, const char* IP, int Port) { sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(Port); serverAddr.sin_addr.s_addr = inet_addr(IP); if (sendto(Socketbit, str, strlen(str), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { return false; } else { return true; } } bool CCSocket::SendData(const char* str, sockaddr_in addr_in){ bool F = sendto(this->Socketbit, str, strlen(str), 0, (sockaddr*)&addr_in, sizeof(addr_in)) != -1; return F; } bool CCSocket::UDPSendByte(const char* str,ByteHander len ,const char* IP, int Port) { sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(Port); serverAddr.sin_addr.s_addr = inet_addr(IP); if (sendto(Socketbit, str, len, 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { return false; } else { return true; } } ByteHander CCSocket::RecvData(char* buffer,ByteHander lens) { int len = recv(Socketbit,buffer,lens,0); return len; } bool CCSocket::GetDateHead(char* data, ByteHander* size) { int i = sizeof(data); memcpy(size,data,i); if (size!=0) { return true; } return false; } bool CCSocket::GetStrHead(char* data, ByteHander size) { for (int i = 0; i < HanderSize; i++) { data[i] = '\0'; } data[0] = '-'; memcpy(data, &size, sizeof(ByteHander)); if (data[0] == '-') { return false; } return true; } ByteHander CCSocket::UDPRecvData(char* buffer,ByteHander lens,CCHostInfo* info) { sockaddr_in A = {}; socklen_t clientSize = sizeof(A); int bytesReceived = recvfrom(this->Socketbit, buffer, lens+1, 0,(struct sockaddr *)&A, &clientSize); char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &A.sin_addr, IP, INET_ADDRSTRLEN); info->IPAddress = IP; info->Port = ntohs(A.sin_port); return bytesReceived; } void CCSocket::Close() { Stop = false; close(Socketbit); } bool CCSocket::Send(const void *__buf, size_t __n, int __flags) { int err = send(Socketbit, __buf, __n, __flags); if(err == -1) { return false; } return true; } bool CCSocket::operator==(CCSocket socket) { if(socket.Socketbit == this->Socketbit) { return true; } return false; } bool CCSocket::operator!=(CCSocket socket) { if(socket.Socketbit != this->Socketbit) { return true; } return false; } CCHostInfo CCSocket::GetClientHost() { CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &client.sin_addr, IP, INET_ADDRSTRLEN); hostInfo.IPAddress = IP; hostInfo.Port = ntohs(client.sin_port); return hostInfo; } CCHostInfo CCSocket::GetLocalHost(){ CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; inet_ntop(IPVx, &server.sin_addr, IP, INET_ADDRSTRLEN); hostInfo.IPAddress = IP; hostInfo.Port = ntohs(server.sin_port); return hostInfo; } void CCSocket::SetSocketNonBlocking() { int flags = fcntl(this->Socketbit, F_GETFL, 0); if (flags == -1) { perror("fcntl(F_GETFL)"); return; } flags |= O_NONBLOCK; if (fcntl(this->Socketbit, F_SETFL, flags) == -1) { perror("fcntl(F_SETFL)"); } } bool CCSocket::isDataAvailable() { pollfd pfd{}; pfd.fd = this->Socketbit; pfd.events = POLLIN; pfd.revents = 0; int ret = poll(&pfd, 1, 0); // Non-blocking check if (ret == -1) { perror("poll"); return false; } return pfd.revents & POLLIN; } bool CCSocket::isConnectionAlive() { fd_set fds; FD_ZERO(&fds); FD_SET(Socketbit, &fds); timeval timeout = { 0, 0 }; // 非阻塞模式立即返回 int ret = select(Socketbit + 1, &fds, NULL, &fds, &timeout); if (ret < 0) { // 错误处理 return false; } else if (ret > 0) { if (FD_ISSET(Socketbit, &fds)) { if (FD_ISSET(Socketbit, &fds)) { // 检查异常条件 return false; } } } return true; } #else #endif