Reorganize socket classes
This commit is contained in:
68
src/server/socket/clientsocket.cpp
Normal file
68
src/server/socket/clientsocket.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "clientsocket.hpp"
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
|
||||
std::vector<char> ClientSocket::ReadBytes(size_t limit) const
|
||||
{
|
||||
size_t const readChunkSize = 128;
|
||||
|
||||
std::vector<char> buffer;
|
||||
ssize_t totalBytesRead = 0;
|
||||
ssize_t bytesRead = 0;
|
||||
do
|
||||
{
|
||||
buffer.resize(buffer.size() + readChunkSize);
|
||||
bytesRead = read(fileDescriptor, &buffer[totalBytesRead], readChunkSize);
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
throw std::runtime_error("Error reading from filedescriptor");
|
||||
}
|
||||
|
||||
totalBytesRead += bytesRead;
|
||||
} while (bytesRead == readChunkSize && bytesRead < limit);
|
||||
|
||||
buffer.resize(totalBytesRead);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
size_t ClientSocket::WriteBytes(std::vector<char> const & bytes) const
|
||||
{
|
||||
ssize_t totalBytesWritten = 0;
|
||||
size_t const sizeToWrite = bytes.size();
|
||||
while (totalBytesWritten < sizeToWrite)
|
||||
{
|
||||
ssize_t bytesWritten = write(fileDescriptor, &bytes[totalBytesWritten], sizeToWrite - totalBytesWritten);
|
||||
if (bytesWritten <= 0)
|
||||
{
|
||||
throw std::runtime_error("Error writing to filedescriptor");
|
||||
}
|
||||
|
||||
totalBytesWritten += bytesWritten;
|
||||
}
|
||||
|
||||
return totalBytesWritten;
|
||||
}
|
||||
|
||||
ClientSocket::ClientSocket(int _fileDescriptor)
|
||||
: fileDescriptor(_fileDescriptor)
|
||||
{
|
||||
if (_fileDescriptor < 0)
|
||||
{
|
||||
throw std::runtime_error("clientSocket created with invalid file descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
ClientSocket::~ClientSocket()
|
||||
{
|
||||
if (fileDescriptor >= 0)
|
||||
{
|
||||
close(fileDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
ClientSocket::ClientSocket(ClientSocket && other)
|
||||
{
|
||||
fileDescriptor = other.fileDescriptor;
|
||||
|
||||
other.fileDescriptor = -1;
|
||||
}
|
||||
23
src/server/socket/clientsocket.hpp
Normal file
23
src/server/socket/clientsocket.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
class ClientSocket
|
||||
{
|
||||
private:
|
||||
int fileDescriptor;
|
||||
|
||||
public:
|
||||
// Parameter limit is a multiple of 128
|
||||
std::vector<char> ReadBytes(size_t limit = 512) const;
|
||||
|
||||
size_t WriteBytes(std::vector<char> const & bytes) const;
|
||||
|
||||
ClientSocket(int _fileDescriptor);
|
||||
~ClientSocket();
|
||||
|
||||
ClientSocket(ClientSocket && other);
|
||||
|
||||
ClientSocket(ClientSocket & other) = delete;
|
||||
ClientSocket & operator=(ClientSocket & other) = delete;
|
||||
};
|
||||
54
src/server/socket/listeningsocket.cpp
Normal file
54
src/server/socket/listeningsocket.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "listeningsocket.hpp"
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
|
||||
int const connectionLimit = 10;
|
||||
|
||||
ClientSocket ListeningSocket::AcceptNextConnection()
|
||||
{
|
||||
unsigned sockaddrSize = sizeof(sockaddr_in);
|
||||
int connectionFileDescriptor = accept(
|
||||
socketFileDescriptor,
|
||||
reinterpret_cast<sockaddr *>(&socketAddress),
|
||||
&sockaddrSize);
|
||||
|
||||
return ClientSocket(connectionFileDescriptor);
|
||||
}
|
||||
|
||||
ListeningSocket::ListeningSocket(int const port)
|
||||
: socketFileDescriptor(-1),
|
||||
socketAddress()
|
||||
{
|
||||
socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socketFileDescriptor < 0)
|
||||
{
|
||||
throw std::runtime_error("socket creation error");
|
||||
}
|
||||
|
||||
socketAddress.sin_family = AF_INET;
|
||||
socketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
socketAddress.sin_port = htons(port);
|
||||
|
||||
int const bindResult = bind(
|
||||
socketFileDescriptor,
|
||||
reinterpret_cast<sockaddr*>(&socketAddress),
|
||||
sizeof(sockaddr_in));
|
||||
if (bindResult < 0)
|
||||
{
|
||||
throw std::runtime_error("socket bind error");
|
||||
}
|
||||
|
||||
int const listenResult = listen(socketFileDescriptor, connectionLimit);
|
||||
if (listenResult < 0)
|
||||
{
|
||||
throw std::runtime_error("socket listening error");
|
||||
}
|
||||
}
|
||||
|
||||
ListeningSocket::~ListeningSocket()
|
||||
{
|
||||
if (socketFileDescriptor >= 0)
|
||||
{
|
||||
close(socketFileDescriptor);
|
||||
}
|
||||
}
|
||||
20
src/server/socket/listeningsocket.hpp
Normal file
20
src/server/socket/listeningsocket.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "clientsocket.hpp"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
class ListeningSocket
|
||||
{
|
||||
private:
|
||||
int socketFileDescriptor;
|
||||
sockaddr_in socketAddress;
|
||||
|
||||
public:
|
||||
ClientSocket AcceptNextConnection();
|
||||
|
||||
ListeningSocket(int const port);
|
||||
~ListeningSocket();
|
||||
|
||||
ListeningSocket(ListeningSocket & other) = delete;
|
||||
ListeningSocket & operator=(ListeningSocket & other) = delete;
|
||||
};
|
||||
Reference in New Issue
Block a user