Skip to content

Commit

Permalink
Update to v3.0
Browse files Browse the repository at this point in the history
Fixed potential data races #25
Fixed BUFFER_SIZE bugs #27
Added new Send() function usages
Removed unnecessary string copies (converted to const std::string&)
  • Loading branch information
eminfedar committed Apr 27, 2023
1 parent a17b3e1 commit fb72473
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 52 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
*.out
*.app

examples/bin
benchmarks/easysocket/bin
examples/tcp-client
examples/tcp-server
examples/udp-client
examples/udp-server
.vscode
.idea
cmake-build-debug
Expand Down
5 changes: 3 additions & 2 deletions async-sockets/include/basesocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <string>
#include <functional>
#include <cerrno>
#include <atomic>

#define FDR_UNUSED(expr){ (void)(expr); }
#define FDR_ON_ERROR std::function<void(int, std::string)> onError = [](int errorCode, std::string errorMessage){FDR_UNUSED(errorCode); FDR_UNUSED(errorMessage)}
Expand All @@ -26,9 +27,9 @@ class BaseSocket
TCP = SOCK_STREAM,
UDP = SOCK_DGRAM
};
const uint16_t BUFFER_SIZE = 0xFFFF;
sockaddr_in address;
bool isClosed = false;
std::atomic<bool> isClosed{false};
constexpr static uint16_t BUFFER_SIZE = 0x1000; // 4096 bytes

protected:
int sock = 0;
Expand Down
14 changes: 7 additions & 7 deletions async-sockets/include/tcpserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class TCPServer : public BaseSocket
{
public:
// Event Listeners:
std::function<void(TCPSocket *)> onNewConnection = [](TCPSocket* sock){FDR_UNUSED(sock)};
std::function<void(TCPSocket*)> onNewConnection = [](TCPSocket* sock){FDR_UNUSED(sock)};

explicit TCPServer(FDR_ON_ERROR): BaseSocket(onError, SocketType::TCP)
{
Expand All @@ -17,7 +17,7 @@ class TCPServer : public BaseSocket
}

// Binding the server.
void Bind(const char *address, uint16_t port, FDR_ON_ERROR)
void Bind(const char* address, uint16_t port, FDR_ON_ERROR)
{
if (inet_pton(AF_INET, address, &this->address.sin_addr) <= 0)
{
Expand All @@ -28,7 +28,7 @@ class TCPServer : public BaseSocket
this->address.sin_family = AF_INET;
this->address.sin_port = htons(port);

if (bind(this->sock, (const sockaddr *)&this->address, sizeof(this->address)) < 0)
if (bind(this->sock, (const sockaddr*)&this->address, sizeof(this->address)) < 0)
{
onError(errno, "Cannot bind the socket.");
return;
Expand Down Expand Up @@ -58,15 +58,15 @@ class TCPServer : public BaseSocket
}

private:
static void Accept(TCPServer *server, FDR_ON_ERROR)
static void Accept(TCPServer* server, FDR_ON_ERROR)
{
sockaddr_in newSocketInfo;
socklen_t newSocketInfoLength = sizeof(newSocketInfo);

int newSock;
int newSock = -1;
while (!server->isClosed)
{
while ((newSock = accept(server->sock, (sockaddr *)&newSocketInfo, &newSocketInfoLength)) < 0)
if ((newSock = accept(server->sock, (sockaddr*)&newSocketInfo, &newSocketInfoLength)) < 0)
{
if (errno == EBADF || errno == EINVAL) return;

Expand All @@ -76,7 +76,7 @@ class TCPServer : public BaseSocket

if (!server->isClosed && newSock >= 0)
{
TCPSocket *newSocket = new TCPSocket(onError, newSock);
TCPSocket* newSocket = new TCPSocket(onError, newSock);
newSocket->deleteAfterClosed = true;
newSocket->setAddressStruct(newSocketInfo);

Expand Down
20 changes: 10 additions & 10 deletions async-sockets/include/tcpsocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TCPSocket : public BaseSocket
explicit TCPSocket(FDR_ON_ERROR, int socketId = -1) : BaseSocket(onError, TCP, socketId){}

// Send TCP Packages
int Send(const char *bytes, size_t byteslength)
int Send(const char* bytes, size_t byteslength)
{
if (this->isClosed)
return -1;
Expand All @@ -29,9 +29,9 @@ class TCPSocket : public BaseSocket
}
return sent;
}
int Send(std::string message) { return this->Send(message.c_str(), message.length()); }
int Send(const std::string& message) { return this->Send(message.c_str(), message.length()); }

void Connect(std::string host, uint16_t port, std::function<void()> onConnected = [](){}, FDR_ON_ERROR)
void Connect(const char* host, uint16_t port, std::function<void()> onConnected = [](){}, FDR_ON_ERROR)
{
struct addrinfo hints, *res, *it;
memset(&hints, 0, sizeof(hints));
Expand All @@ -40,7 +40,7 @@ class TCPSocket : public BaseSocket

// Get address info from DNS
int status;
if ((status = getaddrinfo(host.c_str(), NULL, &hints, &res)) != 0) {
if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) {
onError(errno, "Invalid address." + std::string(gai_strerror(status)));
return;
}
Expand All @@ -66,7 +66,7 @@ class TCPSocket : public BaseSocket
this->setTimeout(5);

// Try to connect.
if (connect(this->sock, (const sockaddr *)&this->address, sizeof(sockaddr_in)) < 0)
if (connect(this->sock, (const sockaddr*)&this->address, sizeof(sockaddr_in)) < 0)
{
onError(errno, "Connection failed to the host.");
this->setTimeout(0);
Expand Down Expand Up @@ -94,12 +94,12 @@ class TCPSocket : public BaseSocket
bool deleteAfterClosed = false;

private:
static void Receive(TCPSocket *socket)
static void Receive(TCPSocket* socket)
{
char tempBuffer[socket->BUFFER_SIZE];
char tempBuffer[TCPSocket::BUFFER_SIZE];
int messageLength;

while ((messageLength = recv(socket->sock, tempBuffer, socket->BUFFER_SIZE, 0)) > 0)
while ((messageLength = recv(socket->sock, tempBuffer, TCPSocket::BUFFER_SIZE, 0)) > 0)
{
tempBuffer[messageLength] = '\0';
if(socket->onMessageReceived)
Expand All @@ -123,7 +123,7 @@ class TCPSocket : public BaseSocket
tv.tv_sec = seconds;
tv.tv_usec = 0;

setsockopt(this->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
setsockopt(this->sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
setsockopt(this->sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
setsockopt(this->sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
}
};
6 changes: 3 additions & 3 deletions async-sockets/include/udpserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
class UDPServer : public UDPSocket
{
public:
void Bind(std::string IPv4, std::uint16_t port, FDR_ON_ERROR)
void Bind(const char* IPv4, std::uint16_t port, FDR_ON_ERROR)
{
if (inet_pton(AF_INET, IPv4.c_str(), &this->address.sin_addr) <= 0)
if (inet_pton(AF_INET, IPv4, &this->address.sin_addr) <= 0)
{
onError(errno, "Invalid address. Address type not supported.");
return;
Expand All @@ -17,7 +17,7 @@ class UDPServer : public UDPSocket
this->address.sin_family = AF_INET;
this->address.sin_port = htons(port);

if (bind(this->sock, (const sockaddr *)&this->address, sizeof(this->address)) < 0)
if (bind(this->sock, (const sockaddr*)&this->address, sizeof(this->address)) < 0)
{
onError(errno, "Cannot bind the socket.");
return;
Expand Down
42 changes: 25 additions & 17 deletions async-sockets/include/udpsocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class UDPSocket : public BaseSocket
}

// SendTo with no connection
void SendTo(const char *bytes, size_t byteslength, std::string host, uint16_t port, FDR_ON_ERROR)
void SendTo(const char* bytes, size_t byteslength, const char* host, uint16_t port, FDR_ON_ERROR)
{
sockaddr_in hostAddr;

Expand All @@ -36,7 +36,7 @@ class UDPSocket : public BaseSocket
hints.ai_socktype = SOCK_DGRAM;

int status;
if ((status = getaddrinfo(host.c_str(), NULL, &hints, &res)) != 0)
if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0)
{
onError(errno, "Invalid address." + std::string(gai_strerror(status)));
return;
Expand All @@ -46,7 +46,7 @@ class UDPSocket : public BaseSocket
{
if (it->ai_family == AF_INET)
{ // IPv4
memcpy((void *)(&hostAddr), (void *)it->ai_addr, sizeof(sockaddr_in));
memcpy((void* )(&hostAddr), (void* )it->ai_addr, sizeof(sockaddr_in));
break; // for now, just get first ip (ipv4).
}
}
Expand All @@ -56,19 +56,27 @@ class UDPSocket : public BaseSocket
hostAddr.sin_port = htons(port);
hostAddr.sin_family = AF_INET;

if (sendto(this->sock, bytes, byteslength, 0, (sockaddr *)&hostAddr, sizeof(hostAddr)) < 0)
if (sendto(this->sock, bytes, byteslength, 0, (sockaddr*)&hostAddr, sizeof(hostAddr)) < 0)
{
onError(errno, "Cannot send message to the address.");
return;
}
}
void SendTo(std::string message, std::string host, uint16_t port, FDR_ON_ERROR)
void SendTo(const char* bytes, size_t byteslength, const std::string& host, uint16_t port, FDR_ON_ERROR)
{
this->SendTo(bytes, byteslength, host.c_str(), port, onError);
}
void SendTo(const std::string& message, const char* host, uint16_t port, FDR_ON_ERROR)
{
this->SendTo(message.c_str(), message.length(), host, port, onError);
}
void SendTo(const std::string& message, const std::string& host, uint16_t port, FDR_ON_ERROR)
{
this->SendTo(message.c_str(), message.length(), host.c_str(), port, onError);
}

// Send with Connect()
int Send(const char *bytes, size_t byteslength)
int Send(const char* bytes, size_t byteslength)
{
if (this->isClosed)
return -1;
Expand All @@ -80,7 +88,7 @@ class UDPSocket : public BaseSocket
}
return sent;
}
int Send(std::string message)
int Send(const std::string& message)
{
return this->Send(message.c_str(), message.length());
}
Expand All @@ -93,21 +101,21 @@ class UDPSocket : public BaseSocket
this->address.sin_addr.s_addr = ipv4;

// Try to connect.
if (connect(this->sock, (const sockaddr *)&this->address, sizeof(sockaddr_in)) < 0)
if (connect(this->sock, (const sockaddr* )&this->address, sizeof(sockaddr_in)) < 0)
{
onError(errno, "Connection failed to the host.");
return;
}
}
void Connect(std::string host, uint16_t port, FDR_ON_ERROR)
void Connect(const char* host, uint16_t port, FDR_ON_ERROR)
{
struct addrinfo hints, *res, *it;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;

int status;
if ((status = getaddrinfo(host.c_str(), NULL, &hints, &res)) != 0)
if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0)
{
onError(errno, "Invalid address." + std::string(gai_strerror(status)));
return;
Expand All @@ -117,7 +125,7 @@ class UDPSocket : public BaseSocket
{
if (it->ai_family == AF_INET)
{ // IPv4
memcpy((void *)(&this->address), (void *)it->ai_addr, sizeof(sockaddr_in));
memcpy((void* )(&this->address), (void*)it->ai_addr, sizeof(sockaddr_in));
break; // for now, just get first ip (ipv4).
}
}
Expand All @@ -128,14 +136,14 @@ class UDPSocket : public BaseSocket
}

private:
static void Receive(UDPSocket *udpSocket)
static void Receive(UDPSocket* udpSocket)
{
char tempBuffer[udpSocket->BUFFER_SIZE];
char tempBuffer[UDPSocket::BUFFER_SIZE];

while (true)
{
int messageLength;
messageLength = recv(udpSocket->sock, tempBuffer, udpSocket->BUFFER_SIZE, 0);
messageLength = recv(udpSocket->sock, tempBuffer, UDPSocket::BUFFER_SIZE, 0);

if (messageLength < 0)
{
Expand All @@ -153,17 +161,17 @@ class UDPSocket : public BaseSocket
}
}
}
static void ReceiveFrom(UDPSocket *udpSocket)
static void ReceiveFrom(UDPSocket* udpSocket)
{
sockaddr_in hostAddr;
socklen_t hostAddrSize = sizeof(hostAddr);

char tempBuffer[udpSocket->BUFFER_SIZE];
char tempBuffer[UDPSocket::BUFFER_SIZE];

while (true)
{
int messageLength;
messageLength = recvfrom(udpSocket->sock, tempBuffer, udpSocket->BUFFER_SIZE, 0, (sockaddr *)&hostAddr, &hostAddrSize);
messageLength = recvfrom(udpSocket->sock, tempBuffer, UDPSocket::BUFFER_SIZE, 0, (sockaddr* )&hostAddr, &hostAddrSize);

if (messageLength < 0)
{
Expand Down
3 changes: 1 addition & 2 deletions examples/tcp-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ int main()
cout << errorCode << " : " << errorMessage << endl;
});

// You should do an input loop so the program will not end immediately:
// Because socket listenings are non-blocking.
// You should do an input loop, so the program won't terminate immediately
string input;
getline(cin, input);
while (input != "exit")
Expand Down
2 changes: 1 addition & 1 deletion examples/tcp-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int main()
cout << errorCode << " : " << errorMessage << endl;
});

// You should do an input loop so the program will not terminated immediately:
// You should do an input loop, so the program won't terminate immediately
string input;
getline(cin, input);
while (input != "exit")
Expand Down
6 changes: 3 additions & 3 deletions examples/udp-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ using namespace std;
int main()
{
// Our constants:
const string IP = "localhost";
const uint16_t PORT = 8888;
constexpr const char* IP = "localhost";
constexpr uint16_t PORT = 8888;

// Initialize socket.
UDPSocket udpSocket(true); // "true" to use Connection on UDP. Default is "false".
Expand All @@ -28,7 +28,7 @@ int main()
};
*/

// You should do an input loop so the program will not terminated immediately:
// You should do an input loop, so the program won't terminate immediately
string input;
getline(cin, input);
while (input != "exit")
Expand Down
9 changes: 4 additions & 5 deletions examples/udp-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ int main()
/*udpServer.onMessageReceived = [&](string message, string ipv4, uint16_t port) {
//cout << ipv4 << ":" << port << " => " << message << endl;
// Just send without control:
// Echo to client:
udpServer.SendTo("A!", ipv4, port);
};*/

// If you want to use raw byte arrays:

udpServer.onRawMessageReceived = [&](const char* message, int length, string ipv4, uint16_t port) {
//cout << ipv4 << ":" << port << " => " << message << "(" << length << ")" << endl;
cout << ipv4 << ":" << port << " => " << message << "(" << length << ")" << endl;

// Just send without control:
// Echo to client:
udpServer.SendTo(message, length, ipv4, port);
};

Expand All @@ -32,7 +31,7 @@ int main()
cout << errorCode << " : " << errorMessage << endl;
});

// You should do an input loop so the program will not terminated immediately:
// You should do an input loop, so the program won't terminate immediately
string input;
getline(cin, input);
while (input != "exit")
Expand Down

0 comments on commit fb72473

Please sign in to comment.