46 std::string remoteAddress()
const {
return ipToString(this->address); }
47 int remotePort()
const {
return ntohs(this->address.sin_port); }
48 int fileDescriptor()
const {
return this->sock; }
53 bool hasSetNoblock=
false;
60 static std::string ipToString(
const sockaddr_in& addr)
62 char ip[INET_ADDRSTRLEN];
64 struct sockaddr_in in;
65 memset(&in, 0,
sizeof(in));
66 in.sin_family = AF_INET;
67 memcpy(&in.sin_addr, &(addr.sin_addr),
sizeof(
struct in_addr));
68 getnameinfo((
struct sockaddr *)&in,
sizeof(
struct sockaddr_in), ip, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
70 return std::string(ip);
73 BaseSocket(FDR_ON_ERROR, SocketType sockType = TCP,
int socketId = -1)
77 this->sock = (int)socket(AF_INET, sockType, 0);
79 if ( this->sock == -1 )
81 onError(errno,
"Socket creating error.");
86 this->sock = socketId;
88 int rcvBufSize=102400*10;
90 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
92 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, (
char*)&rcvBufSize,
sizeof(rcvBufSize));
94 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, &rcvBufSize,
sizeof(rcvBufSize));
96 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, &rcvBufSize,
sizeof(rcvBufSize));
109 std::function<void(std::string, std::string, uint16_t)> onMessageReceived;
110 std::function<void(
const char*,
size_t, std::string, uint16_t)> onRawMessageReceived;
111 bool isUseConnect =
false;
117 closesocket(this->sock);
119 shutdown(this->sock, SHUT_RDWR);
125 explicit UDPSocket(
bool useConnect =
false, FDR_ON_ERROR,
int socketId = -1):
BaseSocket(onError, SocketType::UDP, socketId)
127 this->isUseConnect=useConnect;
131 void StartRecvThread()
134 if (this->isUseConnect)
136 std::thread t(Receive,
this);
141 std::thread t(ReceiveFrom,
this);
149 int SendTo(
const char* bytes,
size_t byteslength,
const char* host, uint16_t port, FDR_ON_ERROR)
151 sockaddr_in hostAddr;
154 if((hostAddr.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
155 onError(errno,
"SendTo: Invalid address. Address type not supported.");
181 hostAddr.sin_port = htons(port);
182 hostAddr.sin_family = AF_INET;
184 int sent_length = sendto(this->sock, bytes, (
int)byteslength, 0, (sockaddr*)&hostAddr,
sizeof(hostAddr));
185 if (sent_length == -1)
187 onError(errno,
"Cannot send message to the address.");
194 int SendTo(
const char* bytes,
size_t byteslength,
const std::string& host, uint16_t port, FDR_ON_ERROR)
196 return this->SendTo(bytes, byteslength, host.c_str(), port, onError);
199 int SendTo(
const std::string& message,
const char* host, uint16_t port, FDR_ON_ERROR)
201 return this->SendTo(message.c_str(), message.length(), host, port, onError);
204 int SendTo(
const std::string& message,
const std::string& host, uint16_t port, FDR_ON_ERROR)
206 return this->SendTo(message.c_str(), message.length(), host.c_str(), port, onError);
210 int Send(
const char* bytes,
size_t byteslength) {
return send(this->sock, bytes, (
int)byteslength, 0); }
212 int Send(
const std::string& message) {
return this->Send(message.c_str(), message.length()); }
215 void Connect(uint32_t ipv4, uint16_t port, FDR_ON_ERROR)
217 this->address.sin_family = AF_INET;
218 this->address.sin_port = htons(port);
219 this->address.sin_addr.s_addr = ipv4;
222 int status = connect(this->sock, (
const sockaddr* )&this->address,
sizeof(sockaddr_in));
225 onError(errno,
"Connection failed to the host.");
230 void Connect(
const char* host, uint16_t port, FDR_ON_ERROR)
255 if((this->address.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
256 onError(errno,
"SendTo: Invalid address. Address type not supported.");
258 this->Connect((uint32_t)this->address.sin_addr.s_addr, port, onError);
261 void Connect(
const std::string& host, uint16_t port, FDR_ON_ERROR) { this->Connect(host.c_str(), port, onError); }
264 static void Receive(
UDPSocket* udpSocket)
266 char tempBuffer[BUFFER_SIZE_RFLY+1];
267 size_t messageLength;
269 while ((messageLength = recv(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0)) != -1)
272 tempBuffer[messageLength] =
'\0';
273 if (udpSocket->onMessageReceived)
274 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
276 if (udpSocket->onRawMessageReceived)
277 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
281 static void ReceiveFrom(
UDPSocket* udpSocket)
284 sockaddr_in hostAddr;
285 socklen_t hostAddrSize =
sizeof(hostAddr);
287 char tempBuffer[BUFFER_SIZE_RFLY+1];
288 size_t messageLength;
290 while ((messageLength = recvfrom(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0, (sockaddr* )&hostAddr, &hostAddrSize)) != -1)
293 tempBuffer[messageLength] =
'\0';
294 if (udpSocket->onMessageReceived)
295 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(hostAddr), ntohs(hostAddr.sin_port));
297 if (udpSocket->onRawMessageReceived)
298 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(hostAddr), ntohs(hostAddr.sin_port));
309 void Bind(
const char* addressin, uint16_t port, FDR_ON_ERROR)
324 if((this->address.sin_addr.s_addr =inet_addr(addressin))==INADDR_NONE){
325 onError(errno,
"Invalid address. Address type not supported.");
328 this->address.sin_family = AF_INET;
329 this->address.sin_port = htons(port);
336 status = setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, (
char*)&bOpt,
sizeof(bOpt));
339 onError(errno,
"Cannot set SO_REUSEADDR the socket.");
351 setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, &flag0,
sizeof(flag0) );
356 status = bind(this->sock, (
const sockaddr*)&this->address,
sizeof(this->address));
359 onError(errno,
"Cannot bind the socket.");
367 void Bind(uint16_t port, FDR_ON_ERROR)
370 this->Bind(
"0.0.0.0", port, onError);
374 void setMulticast(
const char* GROUP_IP, FDR_ON_ERROR)
377 struct ip_mreq vmreq;
379 if((vmreq.imr_multiaddr.s_addr =inet_addr(GROUP_IP))==INADDR_NONE){
380 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
382 if((vmreq.imr_interface.s_addr =inet_addr(
"0.0.0.0"))==INADDR_NONE){
383 onError(errno,
"setMulticast: Invalid address. Address type not supported.");
390 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char*)&vmreq,
sizeof(vmreq));
392 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vmreq,
sizeof(vmreq));
397 onError(errno,
"setsockopt(IP_ADD_MEMBERSHIP) failed.");
403 void setBroadcast(
bool value, FDR_ON_ERROR)
405 int broadcast =
static_cast<int>(value);
407 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (
char*)&broadcast,
sizeof broadcast);
409 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast);
413 onError(errno,
"setsockopt(SO_BROADCAST) failed.");
418 int RecvNoblock(
char * buf, std::string &ip,
int &port,
int maxrecvlen=BUFFER_SIZE_RFLY)
420 if(!this->hasSetNoblock){
421 nonblockingsocket(this->sock);
422 this->hasSetNoblock=
true;
426 sockaddr_in hostAddr;
427 socklen_t hostAddrSize =
sizeof(hostAddr);
430 recvlen=recvfrom(this->sock, buf, maxrecvlen, 0, (
struct sockaddr *)&hostAddr, &hostAddrSize);
432 recvlen=recvfrom(this->sock, buf, maxrecvlen, MSG_DONTWAIT, (
struct sockaddr *)&hostAddr, (socklen_t *)(&hostAddrSize));
435 ip=ipToString(hostAddr);
436 port = ntohs(hostAddr.sin_port);