51 std::string remoteAddress()
const {
return ipToString(this->address); }
52 int remotePort()
const {
return ntohs(this->address.sin_port); }
53 int fileDescriptor()
const {
return this->sock; }
58 bool hasSetNoblock=
false;
65 static std::string ipToString(
const sockaddr_in& addr)
67 char ip[INET_ADDRSTRLEN];
69 struct sockaddr_in in;
70 memset(&in, 0,
sizeof(in));
71 in.sin_family = AF_INET;
72 memcpy(&in.sin_addr, &(addr.sin_addr),
sizeof(
struct in_addr));
73 getnameinfo((
struct sockaddr *)&in,
sizeof(
struct sockaddr_in), ip, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
75 return std::string(ip);
78 static bool isVirtualMachineAdapter(
const std::string& adapterName) {
79 std::vector<std::string> vmKeywords = {
80 "VMware",
"VirtualBox",
"Hyper-V",
"QEMU"
82 for (
const auto& keyword : vmKeywords) {
83 if (adapterName.find(keyword) != std::string::npos) {
91 static std::vector<std::string> getStaticIPAddresses() {
92 std::vector<std::string> staticIPs;
96 if (GetAdaptersInfo(NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
97 PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)malloc(outBufLen);
100 if (GetAdaptersInfo(pAdapterInfo, &outBufLen) == NO_ERROR) {
101 PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
103 std::string adapterName = pAdapter->Description;
105 if (!isVirtualMachineAdapter(adapterName)) {
107 if (pAdapter->DhcpEnabled == FALSE) {
108 IP_ADDR_STRING* pIpAddr = &pAdapter->IpAddressList;
110 staticIPs.emplace_back(pIpAddr->IpAddress.String);
111 pIpAddr = pIpAddr->Next;
115 pAdapter = pAdapter->Next;
126 BaseSocket(FDR_ON_ERROR, SocketType sockType = TCP,
int socketId = -1)
130 this->sock = (int)socket(AF_INET, sockType, 0);
132 if ( this->sock == -1 )
134 onError(errno,
"Socket creating error.");
139 this->sock = socketId;
141 int rcvBufSize=102400*10;
143 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
144 rcvBufSize=102400*10;
145 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
147 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, &rcvBufSize,
sizeof(rcvBufSize));
148 rcvBufSize=102400*10;
149 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, &rcvBufSize,
sizeof(rcvBufSize));
162 std::function<void(std::string, std::string, uint16_t)> onMessageReceived;
163 std::function<void(
const char*,
size_t, std::string, uint16_t)> onRawMessageReceived;
164 bool isUseConnect =
false;
170 closesocket(this->sock);
172 shutdown(this->sock, SHUT_RDWR);
178 explicit UDPSocket(
bool useConnect =
false, FDR_ON_ERROR,
int socketId = -1):
BaseSocket(onError, SocketType::UDP, socketId)
180 this->isUseConnect=useConnect;
184 void StartRecvThread()
187 if (this->isUseConnect)
189 std::thread t(Receive,
this);
194 std::thread t(ReceiveFrom,
this);
202 int SendTo(
const char* bytes,
size_t byteslength,
const char* host, uint16_t port, FDR_ON_ERROR)
204 sockaddr_in hostAddr;
207 if((hostAddr.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
208 onError(errno,
"SendTo: Invalid address. Address type not supported.");
234 hostAddr.sin_port = htons(port);
235 hostAddr.sin_family = AF_INET;
237 int sent_length = sendto(this->sock, bytes, (
int)byteslength, 0, (sockaddr*)&hostAddr,
sizeof(hostAddr));
238 if (sent_length == -1)
240 onError(errno,
"Cannot send message to the address.");
247 int SendTo(
const char* bytes,
size_t byteslength,
const std::string& host, uint16_t port, FDR_ON_ERROR)
249 return this->SendTo(bytes, byteslength, host.c_str(), port, onError);
252 int SendTo(
const std::string& message,
const char* host, uint16_t port, FDR_ON_ERROR)
254 return this->SendTo(message.c_str(), message.length(), host, port, onError);
257 int SendTo(
const std::string& message,
const std::string& host, uint16_t port, FDR_ON_ERROR)
259 return this->SendTo(message.c_str(), message.length(), host.c_str(), port, onError);
263 int Send(
const char* bytes,
size_t byteslength) {
return send(this->sock, bytes, (
int)byteslength, 0); }
265 int Send(
const std::string& message) {
return this->Send(message.c_str(), message.length()); }
268 void Connect(uint32_t ipv4, uint16_t port, FDR_ON_ERROR)
270 this->address.sin_family = AF_INET;
271 this->address.sin_port = htons(port);
272 this->address.sin_addr.s_addr = ipv4;
275 int status = connect(this->sock, (
const sockaddr* )&this->address,
sizeof(sockaddr_in));
278 onError(errno,
"Connection failed to the host.");
283 void Connect(
const char* host, uint16_t port, FDR_ON_ERROR)
308 if((this->address.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
309 onError(errno,
"SendTo: Invalid address. Address type not supported.");
311 this->Connect((uint32_t)this->address.sin_addr.s_addr, port, onError);
314 void Connect(
const std::string& host, uint16_t port, FDR_ON_ERROR) { this->Connect(host.c_str(), port, onError); }
317 static void Receive(
UDPSocket* udpSocket)
319 char tempBuffer[BUFFER_SIZE_RFLY+1];
320 size_t messageLength;
322 while ((messageLength = recv(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0)) != -1)
325 tempBuffer[messageLength] =
'\0';
326 if (udpSocket->onMessageReceived)
327 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
329 if (udpSocket->onRawMessageReceived)
330 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
334 static void ReceiveFrom(
UDPSocket* udpSocket)
337 sockaddr_in hostAddr;
338 socklen_t hostAddrSize =
sizeof(hostAddr);
340 char tempBuffer[BUFFER_SIZE_RFLY+1];
341 size_t messageLength;
343 while ((messageLength = recvfrom(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0, (sockaddr* )&hostAddr, &hostAddrSize)) != -1)
346 tempBuffer[messageLength] =
'\0';
347 if (udpSocket->onMessageReceived)
348 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(hostAddr), ntohs(hostAddr.sin_port));
350 if (udpSocket->onRawMessageReceived)
351 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(hostAddr), ntohs(hostAddr.sin_port));
362 bool needFilter=
false;
364 void Bind(
const char* addressin, uint16_t port, FDR_ON_ERROR)
379 if((this->address.sin_addr.s_addr =inet_addr(addressin))==INADDR_NONE){
380 onError(errno,
"Invalid address. Address type not supported.");
383 this->address.sin_family = AF_INET;
384 this->address.sin_port = htons(port);
391 status = setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, (
char*)&bOpt,
sizeof(bOpt));
394 onError(errno,
"Cannot set SO_REUSEADDR the socket.");
406 setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, &flag0,
sizeof(flag0) );
411 status = bind(this->sock, (
const sockaddr*)&this->address,
sizeof(this->address));
414 onError(errno,
"Cannot bind the socket.");
422 void Bind(uint16_t port, FDR_ON_ERROR)
425 this->Bind(
"0.0.0.0", port, onError);
432 void BindAuto(
bool isReal, uint16_t port, FDR_ON_ERROR)
434 std::cout<<
"Bind Auto, with ip:\t";
437 std::vector<std::string> staticIPs = getStaticIPAddresses();
438 std::string targetIP =
"192.168.151.168";
439 auto it = std::find(staticIPs.begin(), staticIPs.end(), targetIP);
440 if (it != staticIPs.end()) {
441 this->Bind(
"192.168.151.168", port, onError);
442 std::cout<<targetIP<<std::endl;
444 std::string bindIP =
"0.0.0.0";
445 for (
const auto& ip : staticIPs) {
446 if (ip !=
"0.0.0.0") {
451 this->Bind(bindIP.c_str(), port, onError);
452 std::cout<<bindIP<<std::endl;
455 this->Bind(
"127.0.0.1", port, onError);
456 std::cout<<
"127.0.0.1"<<std::endl;
461 void setMulticast(
const char* GROUP_IP, FDR_ON_ERROR)
464 struct ip_mreq vmreq;
466 if((vmreq.imr_multiaddr.s_addr =inet_addr(GROUP_IP))==INADDR_NONE){
467 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
469 if((vmreq.imr_interface.s_addr =inet_addr(
"0.0.0.0"))==INADDR_NONE){
470 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
477 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char*)&vmreq,
sizeof(vmreq));
479 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vmreq,
sizeof(vmreq));
484 onError(errno,
"setsockopt(IP_ADD_MEMBERSHIP) failed.");
490 void setBroadcast(
bool value, FDR_ON_ERROR)
492 int broadcast =
static_cast<int>(value);
494 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (
char*)&broadcast,
sizeof broadcast);
496 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast);
500 onError(errno,
"setsockopt(SO_BROADCAST) failed.");
505 int RecvNoblock(
char * buf, std::string &ip,
int &port,
int maxrecvlen=BUFFER_SIZE_RFLY)
507 if(!this->hasSetNoblock){
508 nonblockingsocket(this->sock);
509 this->hasSetNoblock=
true;
513 sockaddr_in hostAddr;
514 socklen_t hostAddrSize =
sizeof(hostAddr);
517 recvlen=recvfrom(this->sock, buf, maxrecvlen, 0, (
struct sockaddr *)&hostAddr, &hostAddrSize);
519 recvlen=recvfrom(this->sock, buf, maxrecvlen, MSG_DONTWAIT, (
struct sockaddr *)&hostAddr, (socklen_t *)(&hostAddrSize));
522 ip=ipToString(hostAddr);
523 port = ntohs(hostAddr.sin_port);