250 std::string remoteAddress()
const {
return ipToString(this->address); }
251 int remotePort()
const {
return ntohs(this->address.sin_port); }
252 int fileDescriptor()
const {
return this->sock; }
257 bool hasSetNoblock=
false;
264 static std::string ipToString(
const sockaddr_in& addr)
266 char ip[INET_ADDRSTRLEN];
268 struct sockaddr_in in;
269 memset(&in, 0,
sizeof(in));
270 in.sin_family = AF_INET;
271 memcpy(&in.sin_addr, &(addr.sin_addr),
sizeof(
struct in_addr));
272 getnameinfo((
struct sockaddr *)&in,
sizeof(
struct sockaddr_in), ip, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
274 return std::string(ip);
277 static bool isVirtualMachineAdapter(
const std::string& adapterName) {
278 std::vector<std::string> vmKeywords = {
279 "VMware",
"VirtualBox",
"Hyper-V",
"QEMU"
281 for (
const auto& keyword : vmKeywords) {
282 if (adapterName.find(keyword) != std::string::npos) {
290 static std::vector<std::string> getStaticIPAddresses() {
291 std::vector<std::string> staticIPs;
295 if (GetAdaptersInfo(NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
296 PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)malloc(outBufLen);
299 if (GetAdaptersInfo(pAdapterInfo, &outBufLen) == NO_ERROR) {
300 PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
302 std::string adapterName = pAdapter->Description;
304 if (!isVirtualMachineAdapter(adapterName)) {
306 if (pAdapter->DhcpEnabled == FALSE) {
307 IP_ADDR_STRING* pIpAddr = &pAdapter->IpAddressList;
309 staticIPs.emplace_back(pIpAddr->IpAddress.String);
310 pIpAddr = pIpAddr->Next;
314 pAdapter = pAdapter->Next;
325 BaseSocket(FDR_ON_ERROR, SocketType sockType = TCP,
int socketId = -1)
329 this->sock = (int)socket(AF_INET, sockType, 0);
331 if ( this->sock == -1 )
333 onError(errno,
"Socket creating error.");
338 this->sock = socketId;
340 int rcvBufSize=102400*10;
342 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
343 rcvBufSize=102400*10;
344 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
346 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, &rcvBufSize,
sizeof(rcvBufSize));
347 rcvBufSize=102400*10;
348 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, &rcvBufSize,
sizeof(rcvBufSize));
354 virtual ~BaseSocket(){}
358class UDPSocket :
public BaseSocket
361 std::function<void(std::string, std::string, uint16_t)> onMessageReceived;
362 std::function<void(
const char*,
size_t, std::string, uint16_t)> onRawMessageReceived;
363 bool isUseConnect =
false;
369 closesocket(this->sock);
371 shutdown(this->sock, SHUT_RDWR);
377 explicit UDPSocket(
bool useConnect =
false, FDR_ON_ERROR,
int socketId = -1): BaseSocket(onError, SocketType::UDP, socketId)
379 this->isUseConnect=useConnect;
383 void StartRecvThread()
386 if (this->isUseConnect)
388 std::thread t(Receive,
this);
393 std::thread t(ReceiveFrom,
this);
401 int SendTo(
const char* bytes,
size_t byteslength,
const char* host, uint16_t port, FDR_ON_ERROR)
403 sockaddr_in hostAddr;
406 if((hostAddr.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
407 onError(errno,
"SendTo: Invalid address. Address type not supported.");
433 hostAddr.sin_port = htons(port);
434 hostAddr.sin_family = AF_INET;
436 int sent_length = sendto(this->sock, bytes, (
int)byteslength, 0, (sockaddr*)&hostAddr,
sizeof(hostAddr));
437 if (sent_length == -1)
439 onError(errno,
"Cannot send message to the address.");
446 int SendTo(
const char* bytes,
size_t byteslength,
const std::string& host, uint16_t port, FDR_ON_ERROR)
448 return this->SendTo(bytes, byteslength, host.c_str(), port, onError);
451 int SendTo(
const std::string& message,
const char* host, uint16_t port, FDR_ON_ERROR)
453 return this->SendTo(message.c_str(), message.length(), host, port, onError);
456 int SendTo(
const std::string& message,
const std::string& host, uint16_t port, FDR_ON_ERROR)
458 return this->SendTo(message.c_str(), message.length(), host.c_str(), port, onError);
462 int Send(
const char* bytes,
size_t byteslength) {
return send(this->sock, bytes, (
int)byteslength, 0); }
464 int Send(
const std::string& message) {
return this->Send(message.c_str(), message.length()); }
467 void Connect(uint32_t ipv4, uint16_t port, FDR_ON_ERROR)
469 this->address.sin_family = AF_INET;
470 this->address.sin_port = htons(port);
471 this->address.sin_addr.s_addr = ipv4;
474 int status = connect(this->sock, (
const sockaddr* )&this->address,
sizeof(sockaddr_in));
477 onError(errno,
"Connection failed to the host.");
482 void Connect(
const char* host, uint16_t port, FDR_ON_ERROR)
507 if((this->address.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
508 onError(errno,
"SendTo: Invalid address. Address type not supported.");
510 this->Connect((uint32_t)this->address.sin_addr.s_addr, port, onError);
513 void Connect(
const std::string& host, uint16_t port, FDR_ON_ERROR) { this->Connect(host.c_str(), port, onError); }
516 static void Receive(UDPSocket* udpSocket)
518 char tempBuffer[BUFFER_SIZE_RFLY+1];
519 size_t messageLength;
521 while ((messageLength = recv(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0)) != -1)
524 tempBuffer[messageLength] =
'\0';
525 if (udpSocket->onMessageReceived)
526 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
528 if (udpSocket->onRawMessageReceived)
529 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
533 static void ReceiveFrom(UDPSocket* udpSocket)
536 sockaddr_in hostAddr;
537 socklen_t hostAddrSize =
sizeof(hostAddr);
539 char tempBuffer[BUFFER_SIZE_RFLY+1];
540 size_t messageLength;
542 while ((messageLength = recvfrom(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0, (sockaddr* )&hostAddr, &hostAddrSize)) != -1)
545 tempBuffer[messageLength] =
'\0';
546 if (udpSocket->onMessageReceived)
547 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(hostAddr), ntohs(hostAddr.sin_port));
549 if (udpSocket->onRawMessageReceived)
550 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(hostAddr), ntohs(hostAddr.sin_port));
561 bool needFilter=
false;
563 void Bind(
const char* addressin, uint16_t port, FDR_ON_ERROR)
578 if((this->address.sin_addr.s_addr =inet_addr(addressin))==INADDR_NONE){
579 onError(errno,
"Invalid address. Address type not supported.");
582 this->address.sin_family = AF_INET;
583 this->address.sin_port = htons(port);
590 status = setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, (
char*)&bOpt,
sizeof(bOpt));
593 onError(errno,
"Cannot set SO_REUSEADDR the socket.");
605 setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, &flag0,
sizeof(flag0) );
610 status = bind(this->sock, (
const sockaddr*)&this->address,
sizeof(this->address));
613 onError(errno,
"Cannot bind the socket.");
621 void Bind(uint16_t port, FDR_ON_ERROR)
624 this->Bind(
"0.0.0.0", port, onError);
631 void BindAuto(
bool isReal, uint16_t port, FDR_ON_ERROR)
633 std::cout<<
"Bind Auto, with ip:\t";
636 std::vector<std::string> staticIPs = getStaticIPAddresses();
637 std::string targetIP =
"192.168.151.168";
638 auto it = std::find(staticIPs.begin(), staticIPs.end(), targetIP);
639 if (it != staticIPs.end()) {
640 this->Bind(
"192.168.151.168", port, onError);
641 std::cout<<targetIP<<std::endl;
643 std::string bindIP =
"0.0.0.0";
644 for (
const auto& ip : staticIPs) {
645 if (ip !=
"0.0.0.0") {
650 this->Bind(bindIP.c_str(), port, onError);
651 std::cout<<bindIP<<std::endl;
654 this->Bind(
"127.0.0.1", port, onError);
655 std::cout<<
"127.0.0.1"<<std::endl;
660 void setMulticast(
const char* GROUP_IP, FDR_ON_ERROR)
663 struct ip_mreq vmreq;
665 if((vmreq.imr_multiaddr.s_addr =inet_addr(GROUP_IP))==INADDR_NONE){
666 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
668 if((vmreq.imr_interface.s_addr =inet_addr(
"0.0.0.0"))==INADDR_NONE){
669 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
676 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char*)&vmreq,
sizeof(vmreq));
678 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vmreq,
sizeof(vmreq));
683 onError(errno,
"setsockopt(IP_ADD_MEMBERSHIP) failed.");
689 void setBroadcast(
bool value, FDR_ON_ERROR)
691 int broadcast =
static_cast<int>(value);
693 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (
char*)&broadcast,
sizeof broadcast);
695 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast);
699 onError(errno,
"setsockopt(SO_BROADCAST) failed.");
704 int RecvNoblock(
char * buf, std::string &ip,
int &port,
int maxrecvlen=BUFFER_SIZE_RFLY)
706 if(!this->hasSetNoblock){
707 nonblockingsocket(this->sock);
708 this->hasSetNoblock=
true;
712 sockaddr_in hostAddr;
713 socklen_t hostAddrSize =
sizeof(hostAddr);
716 recvlen=recvfrom(this->sock, buf, maxrecvlen, 0, (
struct sockaddr *)&hostAddr, &hostAddrSize);
718 recvlen=recvfrom(this->sock, buf, maxrecvlen, MSG_DONTWAIT, (
struct sockaddr *)&hostAddr, (socklen_t *)(&hostAddrSize));
721 ip=ipToString(hostAddr);
722 port = ntohs(hostAddr.sin_port);