frnetlib/src/Socket.cpp

88 lines
2.3 KiB
C++

//
// Created by fred on 06/12/16.
//
#include "frnetlib/Socket.h"
namespace fr
{
#ifdef _WIN32
WSADATA Socket::wsaData = WSADATA();
uint32_t Socket::instance_count = 0;
#endif // _WIN32
Socket::Socket() noexcept
: is_blocking(true),
is_connected(false)
{
#ifdef _WIN32
if(instance_count == 0)
{
int wsa_result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(wsa_result != 0)
{
std::cout << "Failed to initialise WSA." << std::endl;
return;
}
}
instance_count++;
#endif // _WIN32
}
Socket::Status Socket::send(const Packet &packet)
{
//Get packet data
std::string data = packet.get_buffer();
//Prepend packet length
uint32_t length = htonl((uint32_t)data.size());
data.insert(0, "1234");
memcpy(&data[0], &length, sizeof(uint32_t));
//Send it
return send_raw(data.c_str(), data.size());
}
Socket::Status Socket::receive(Packet &packet)
{
Socket::Status status;
//Try to read packet length
uint32_t packet_length = 0;
status = receive_all(&packet_length, sizeof(packet_length));
if(status != Socket::Status::Success)
return status;
packet_length = ntohl(packet_length);
//Now we've got the length, read the rest of the data in
std::string data(packet_length, 'c');
status = receive_all(&data[0], packet_length);
if(status != Socket::Status::Success)
return status;
//Set the packet to what we've read
packet.set_buffer(std::move(data));
return Socket::Status::Success;
}
Socket::Status Socket::receive_all(void *dest, size_t size)
{
size_t bytes_read = 0;
while(bytes_read < size)
{
size_t read = 0;
Socket::Status status = receive_raw((uintptr_t*)dest + bytes_read, size, read);
if(status == Socket::Status::Success)
bytes_read += read;
else
return status;
}
return Socket::Status::Success;
}
void Socket::shutdown()
{
::shutdown(get_socket_descriptor(), 0);
}
}