Comments 3
Жуть какая.
Что мешало сделать отдельные методы int network_init(); и void network_done(); Что бы единообразно в разных ос инициализировать сеть.
addrinfo* GetServerLocalAddress() возвращает не адрес а создаёт список адресов, которые еще потом надо не забыть освободить с помощью freeaddrinfo. Это в рамках C++ не в какие ворота.
А если у нас адрес в ipv6?
Вместо switch лучше сгородить dispatcher сообщений
нет обработки сигналов
А если вдруг понадобиться заменить канал на защищенный ssl или использовать прокси то всё опять переписывать?
Сами с json не стали связываться использовали готовую либу. Так что мешало и для сети поступить так же?
В общем вместо того что бы скрыть недостатки posix и винды вы наружу выворачиваете. Весь common.h можно было оставить в реализации и не заставлять компилятор елозить по системным хидерам, а выкатить только интерфейс для работы клиента и сервера без инклюдов винды и posix.
Note, however, select() is becoming obsolete for modern network applications and C++20 coroutines are growing more popular
Как это вообще с C++20 связано, вместо select есть epoll. И если надо coroutines можно в обычно C организовать даже на старых компиляторах как stack-less так и stack-full. В C++20 просто появился дополнительный механизм для реализации.
Итого: Для простого примера слишком сложно, а до образцовой реализации слишком далеко.
Creating your own messaging protocol and implementing socket communication in C++ involves several steps. Below, I'll provide a basic example of how you can achieve this. This example will cover a simple client-server architecture using TCP sockets.
Server Side (Messaging Protocol and Socket Handling)
#include
#include
#include <sys/socket.h>
#include <netinet/in.h>
const int PORT = 8080;
// Define your messaging protocol
struct Message {
int type; // You can define different message types
char data[1024]; // Actual message data
};
int main() {
// Create socket
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
std::cerr << "Error creating socket\n";
return -1;
}
// Bind the socket to a specific address and port
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
std::cerr << "Error binding socket\n";
close(serverSocket);
return -1;
}
// Listen for incoming connections
if (listen(serverSocket, 10) == -1) {
std::cerr << "Error listening for connections\n";
close(serverSocket);
return -1;
}
std::cout << "Server listening on port " << PORT << std::endl;
// Accept connections and handle messages
while (true) {
sockaddr_in clientAddr{};
socklen_t clientLen = sizeof(clientAddr);
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientLen);
if (clientSocket == -1) {
std::cerr << "Error accepting connection\n";
continue;
}
std::cout << "Connection accepted from " << inet_ntoa(clientAddr.sin_addr) << std::endl;
// Handle messages from the client
Message receivedMessage;
while (recv(clientSocket, &receivedMessage, sizeof(receivedMessage), 0) > 0) {
// Process the received message
std::cout << "Received message of type " << receivedMessage.type << ": " << receivedMessage.data << std::endl;
// Example: Respond to the client
Message responseMessage;
responseMessage.type = 1;
strcpy(responseMessage.data, "Hello, client!");
send(clientSocket, &responseMessage, sizeof(responseMessage), 0);
}
close(clientSocket);
std::cout << "Connection closed with " << inet_ntoa(clientAddr.sin_addr) << std::endl;
}
// Close the server socket
close(serverSocket);
return 0;
Creating your own messaging protocol and implementing socket communication in C++ involves several steps. Below, I'll provide a basic example of how you can achieve this. This example will cover a simple client-server architecture using TCP sockets.
Server Side (Messaging Protocol and Socket Handling)
cpp
Copy code
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
const int PORT = 8080;
// Define your messaging protocol
struct Message {
int type; // You can define different message types
char data[1024]; // Actual message data
};
int main() {
// Create socket
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
std::cerr << "Error creating socket\n";
return -1;
}
// Bind the socket to a specific address and port
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
std::cerr << "Error binding socket\n";
close(serverSocket);
return -1;
}
// Listen for incoming connections
if (listen(serverSocket, 10) == -1) {
std::cerr << "Error listening for connections\n";
close(serverSocket);
return -1;
}
std::cout << "Server listening on port " << PORT << std::endl;
// Accept connections and handle messages
while (true) {
sockaddr_in clientAddr{};
socklen_t clientLen = sizeof(clientAddr);
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientLen);
if (clientSocket == -1) {
std::cerr << "Error accepting connection\n";
continue;
}
std::cout << "Connection accepted from " << inet_ntoa(clientAddr.sin_addr) << std::endl;
// Handle messages from the client
Message receivedMessage;
while (recv(clientSocket, &receivedMessage, sizeof(receivedMessage), 0) > 0) {
// Process the received message
std::cout << "Received message of type " << receivedMessage.type << ": " << receivedMessage.data << std::endl;
// Example: Respond to the client
Message responseMessage;
responseMessage.type = 1;
strcpy(responseMessage.data, "Hello, client!");
send(clientSocket, &responseMessage, sizeof(responseMessage), 0);
}
close(clientSocket);
std::cout << "Connection closed with " << inet_ntoa(clientAddr.sin_addr) << std::endl;
}
// Close the server socket
close(serverSocket);
return 0;
}
Clien
Clients Side
#include
#include
#include <sys/socket.h>
#include <netinet/in.h>
const int PORT = 8080;
int main() {
// Create socket
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1) {
std::cerr << "Error creating socket\n";
return -1;
}
// Connect to the server
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
std::cerr << "Error connecting to server\n";
close(clientSocket);
return -1;
}
std::cout << "Connected to server\n";
// Send messages to the server
while (true) {
// Example: Send a message of type 1
char messageData[1024];
std::cout << "Enter a message: ";
std::cin.getline(messageData, sizeof(messageData));
Message sendMessage;
sendMessage.type = 1;
strcpy(sendMessage.data, messageData);
send(clientSocket, &sendMessage, sizeof(sendMessage), 0);
// Receive and process the server's response
Message receivedMessage;
recv(clientSocket, &receivedMessage, sizeof(receivedMessage), 0);
std::cout << "Server response of type " << receivedMessage.type << ": " << receivedMessage.data << std::endl;
}
// Close the client socket
close(clientSocket);
return 0;
}
This is a basic example, and in a real-world scenario, you might need to handle error cases more robustly, implement additional security measures, and consider more advanced messaging protocols depending on your application's requirements. Additionally, consider using libraries like Boost.Asio for more advanced and efficient network programming in C++.
How to send messages over sockets and create your own messanging protocols in C++