73 lines
2.1 KiB
C++
73 lines
2.1 KiB
C++
|
#include "Packet.h"
|
||
|
#include <cstdlib>
|
||
|
#include <vector>
|
||
|
#include <cstring>
|
||
|
|
||
|
uint32_t to_network_uint32(uint32_t host) {
|
||
|
return htonl(host);
|
||
|
}
|
||
|
|
||
|
uint32_t from_network_uint32(uint32_t net) {
|
||
|
return ntohl(net);
|
||
|
}
|
||
|
|
||
|
bool send_all(SOCKET sock, const char* data, size_t len) {
|
||
|
size_t totalSent = 0;
|
||
|
while(totalSent < len) {
|
||
|
int sent = send(sock, data + totalSent, static_cast<int>(len - totalSent), 0);
|
||
|
if(sent <= 0)
|
||
|
return false;
|
||
|
totalSent += sent;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool recv_all(SOCKET sock, char* buffer, size_t len) {
|
||
|
size_t totalRecv = 0;
|
||
|
while(totalRecv < len) {
|
||
|
int recvd = recv(sock, buffer + totalRecv, static_cast<int>(len - totalRecv), 0);
|
||
|
if(recvd <= 0)
|
||
|
return false;
|
||
|
totalRecv += recvd;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool sendPacket(SOCKET sock, const Packet& packet) {
|
||
|
// Payload length = 1 byte for type + data length.
|
||
|
uint32_t payloadLen = 1 + static_cast<uint32_t>(packet.data.size());
|
||
|
uint32_t netLen = to_network_uint32(payloadLen);
|
||
|
if(!send_all(sock, reinterpret_cast<const char*>(&netLen), sizeof(netLen)))
|
||
|
return false;
|
||
|
if(!send_all(sock, reinterpret_cast<const char*>(&packet.type), sizeof(packet.type)))
|
||
|
return false;
|
||
|
if(!packet.data.empty()) {
|
||
|
if(!send_all(sock, packet.data.data(), packet.data.size()))
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool receivePacket(SOCKET sock, Packet &packet) {
|
||
|
uint32_t netLen = 0;
|
||
|
if(!recv_all(sock, reinterpret_cast<char*>(&netLen), sizeof(netLen)))
|
||
|
return false;
|
||
|
uint32_t len = from_network_uint32(netLen);
|
||
|
if(len < 1)
|
||
|
return false;
|
||
|
char typeChar;
|
||
|
if(!recv_all(sock, &typeChar, 1))
|
||
|
return false;
|
||
|
packet.type = static_cast<PacketType>(typeChar);
|
||
|
size_t dataLen = len - 1;
|
||
|
if(dataLen > 0) {
|
||
|
std::vector<char> buf(dataLen);
|
||
|
if(!recv_all(sock, buf.data(), dataLen))
|
||
|
return false;
|
||
|
packet.data = std::string(buf.begin(), buf.end());
|
||
|
} else {
|
||
|
packet.data.clear();
|
||
|
}
|
||
|
return true;
|
||
|
}
|