feat(server) Implement binary messaging protocol.
This commit is contained in:
parent
6e935918a3
commit
d21a0df285
16
libbettola/include/bettola/network/message.h
Normal file
16
libbettola/include/bettola/network/message.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace BettolaLib {
|
||||||
|
namespace Network {
|
||||||
|
|
||||||
|
enum class MessageType : unsigned char {
|
||||||
|
PlayerPosition,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MessageHeader {
|
||||||
|
MessageType type;
|
||||||
|
unsigned short size;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace Network. */
|
||||||
|
} /* namespace BettolaLib. */
|
||||||
14
libbettola/include/bettola/network/player_pos_message.h
Normal file
14
libbettola/include/bettola/network/player_pos_message.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
namespace BettolaLib {
|
||||||
|
namespace Network {
|
||||||
|
|
||||||
|
struct PlayerPosMessage {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace Network. */
|
||||||
|
} /* namespace BettolaLib. */
|
||||||
@ -88,12 +88,16 @@ bool Socket::connect(const std::string& ip_address, unsigned short port) {
|
|||||||
_address.sin_family = AF_INET;
|
_address.sin_family = AF_INET;
|
||||||
_address.sin_port = htons(port);
|
_address.sin_port = htons(port);
|
||||||
|
|
||||||
if(inet_pton(AF_INET, ip_address.c_str(), &_address.sin_addr) <= 0) {
|
int pton_ret = inet_pton(AF_INET, ip_address.c_str(), &_address.sin_addr);
|
||||||
perror("Invalid address / Address not supported.");
|
if(pton_ret == 0) {
|
||||||
|
fprintf(stderr, "Invalid address format\n");
|
||||||
|
return false;
|
||||||
|
} else if(pton_ret == -1) {
|
||||||
|
perror("inet_pton failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(::connect(_sockfd, (struct sockaddr*)&_address, sizeof(_address)) <= 0) {
|
if(::connect(_sockfd, (struct sockaddr*)&_address, sizeof(_address)) == -1) {
|
||||||
fprintf(stderr, "Socket::connect() failed for sockfd %d with errno %d: %s\n", _sockfd,
|
fprintf(stderr, "Socket::connect() failed for sockfd %d with errno %d: %s\n", _sockfd,
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
perror("Connection failed.");
|
perror("Connection failed.");
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
#include "bettola.h"
|
#include "bettola.h"
|
||||||
#include "bettola/network/socket.h"
|
#include "bettola/network/socket.h"
|
||||||
#include "bettola/network/net_common.h"
|
#include "bettola/network/net_common.h"
|
||||||
|
#include "network/message.h"
|
||||||
|
#include "network/player_pos_message.h"
|
||||||
|
|
||||||
/* Dacav's resolution ;) */
|
/* Dacav's resolution ;) */
|
||||||
const int SCREEN_WIDTH = 800;
|
const int SCREEN_WIDTH = 800;
|
||||||
@ -82,10 +84,16 @@ int Bettola::run(void) {
|
|||||||
network_time += delta_time;
|
network_time += delta_time;
|
||||||
if(network_time > 2.0) {
|
if(network_time > 2.0) {
|
||||||
/* Send/receive every 2 seconds. */
|
/* Send/receive every 2 seconds. */
|
||||||
send_data("Player position: " + std::to_string(_player.get_x()) + "," +
|
BettolaLib::Network::MessageHeader header;
|
||||||
std::to_string(_player.get_y()));
|
header.type = BettolaLib::Network::MessageType::PlayerPosition;
|
||||||
std::string response = receive_data();
|
header.size = sizeof(BettolaLib::Network::PlayerPosMessage);
|
||||||
printf("Bettola Client (in game loop): Received: '%s'\n", response.c_str());
|
_client_socket.send(&header, sizeof(header));
|
||||||
|
|
||||||
|
BettolaLib::Network::PlayerPosMessage msg;
|
||||||
|
msg.x = _player.get_x();
|
||||||
|
msg.y = _player.get_y();
|
||||||
|
_client_socket.send(&msg, sizeof(msg));
|
||||||
|
|
||||||
network_time = 0.0;
|
network_time = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +245,7 @@ void Bettola::setup_quad(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bettola::init_client_connection(void) {
|
bool Bettola::init_client_connection(void) {
|
||||||
|
SDL_Delay(1000); /* Wait a second before trying to connect. */
|
||||||
if(!_client_socket.create()) {
|
if(!_client_socket.create()) {
|
||||||
printf("Bettola client: Failed to create socket.\n");
|
printf("Bettola client: Failed to create socket.\n");
|
||||||
return false;
|
return false;
|
||||||
@ -252,28 +261,3 @@ bool Bettola::init_client_connection(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bettola::send_data(const std::string& data) {
|
|
||||||
ssize_t bytes_sent = _client_socket.send(data.c_str(), data.length());
|
|
||||||
if(bytes_sent == -1) {
|
|
||||||
perror("Bettola Client: Failed to send data.");
|
|
||||||
} else {
|
|
||||||
printf("Bettola Client: Sent %zd bytes: '%s'\n", bytes_sent, data.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Bettola::receive_data(void) {
|
|
||||||
char buffer[256]; /* Just a small buffer currently. */
|
|
||||||
ssize_t bytes_received = _client_socket.recv(buffer, sizeof(buffer) - 1);
|
|
||||||
if(bytes_received == -1) {
|
|
||||||
perror("Bettola Client: Failed to receive data.");
|
|
||||||
return "";
|
|
||||||
} else if(bytes_received == 0) {
|
|
||||||
printf("Bettola Client: Server disconnected.\n");
|
|
||||||
/* Attempt to reconnect. */
|
|
||||||
_client_socket.close(); /* Close the old socket. */
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
buffer[bytes_received] = '\0';
|
|
||||||
return std::string(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -25,8 +25,6 @@ private:
|
|||||||
bool create_gl_context(void);
|
bool create_gl_context(void);
|
||||||
|
|
||||||
bool init_client_connection(void);
|
bool init_client_connection(void);
|
||||||
void send_data(const std::string& data);
|
|
||||||
std::string receive_data(void);
|
|
||||||
|
|
||||||
void setup_quad(void);
|
void setup_quad(void);
|
||||||
|
|
||||||
|
|||||||
34
srv/main.cpp
34
srv/main.cpp
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "bettola/network/socket.h"
|
#include "bettola/network/socket.h"
|
||||||
#include "bettola/network/net_common.h"
|
#include "bettola/network/net_common.h"
|
||||||
|
#include "bettola/network/message.h"
|
||||||
|
#include "bettola/network/player_pos_message.h"
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("=== Bettola Server: Starting ===\n");
|
printf("=== Bettola Server: Starting ===\n");
|
||||||
@ -39,23 +41,23 @@ int main(void) {
|
|||||||
|
|
||||||
printf("Bettola Server: Client connected!\n");
|
printf("Bettola Server: Client connected!\n");
|
||||||
|
|
||||||
char buffer[256]; /* Small buffer for echo. */
|
while(true) {
|
||||||
ssize_t bytes_received;
|
BettolaLib::Network::MessageHeader header;
|
||||||
do {
|
ssize_t bytes_received = client_socket->recv(&header, sizeof(header));
|
||||||
bytes_received = client_socket->recv(buffer, sizeof(buffer) - 1);
|
|
||||||
if(bytes_received > 0) {
|
|
||||||
buffer[bytes_received] = '\n';
|
|
||||||
printf("Bettola Server: Received from client: '%s'\n", buffer);
|
|
||||||
client_socket->send(buffer, bytes_received); /* Echo back. */
|
|
||||||
} else if(bytes_received == -1) {
|
|
||||||
perror("Bettola Server: Error receiving from client.");
|
|
||||||
}
|
|
||||||
} while(bytes_received > 0);
|
|
||||||
|
|
||||||
/* Let's just keep it connected for now. */
|
if(bytes_received <= 0) {
|
||||||
// printf("Bettola Server: Client disconnected.\n");
|
break;
|
||||||
// client_socket->close();
|
}
|
||||||
// delete client_socket;
|
|
||||||
|
if(header.type == BettolaLib::Network::MessageType::PlayerPosition) {
|
||||||
|
BettolaLib::Network::PlayerPosMessage msg;
|
||||||
|
bytes_received = client_socket->recv(&msg, sizeof(msg));
|
||||||
|
if(bytes_received > 0) {
|
||||||
|
printf("Bettola Server: Received PlayerPosition messgae: x=%.2f, y=%.2f\n",
|
||||||
|
msg.x, msg.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server_socket.close(); /* Shouldn't reach here. */
|
server_socket.close(); /* Shouldn't reach here. */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user