MinimalSocket le ofrece una biblioteca C++ moderna para configurar y crear conexiones de socket tcp y udp , de una manera completamente independiente de la plataforma. Los sistemas soportados son: Windows , cualquier distro Linux y MacOS .
La sección de características detalla las diversas características de MinimalSocket . Lea Uso y ejemplos para ver lo fácil que es usar MinimalSocket .
Este es un proyecto de CMake . Consulte el soporte de CMake para ver cómo se puede integrar esta biblioteca.
Recuerde dejar una estrella en caso de que esta biblioteca le haya resultado útil.
¿Aún no has dejado una estrella ? ¡Hazlo ahora;)!
MinimalSocket le permite crear y configurar conexiones tcp y udp . Los mensajes se pueden enviar y recibir tanto en términos de búfer de bytes como de cadenas. De hecho, esta es en realidad la única capacidad que necesita para un socket, ya que los mensajes más complejos pueden serializarse o internalizarse desde un búfer de bytes utilizando, entre otros, enfoques como Google Protocol Buffers o NanoPb.
Estas son las características más destacables de MinimalSocket :
Esta tabla resume las diferencias entre los comportamientos de bloqueo y no bloqueo del socket que se pueden crear usando MinimalSocket :
Comportamiento de bloqueo, la persona que llama se bloquea hasta que se completa o se alcanza el tiempo de espera (si se especificó uno) | Comportamiento sin bloqueo, las funciones regresan inmediatamente | |
---|---|---|
aceptación de un nuevo cliente (sólo tcp) | El hilo de la persona que llama se absorbe hasta que un nuevo cliente realmente solicita conectarse o se alcanza el tiempo de espera (si se especificó alguno) | si una solicitud de conexión de un cliente ya estaba en cola antes de llamar a la función de aceptación, se devuelve un nuevo controlador de conexión; de lo contrario, se devuelve un nullopt. |
recibir un nuevo mensaje (tcp y udp) | El hilo de la persona que llama se absorbe hasta que se envía un nuevo mensaje al socket o se alcanza el tiempo de espera (si se especificó alguno) | si se envió un mensaje y ya estaba en cola en el búfer del socket antes de llamar a la función de recepción, ese mensaje se devuelve; de lo contrario, se devuelve un mensaje vacío. |
enviar un nuevo mensaje (tcp y udp) | En caso de que el búfer del socket no esté lleno y pueda alojar por completo el mensaje a enviar, el mensaje se escribe realmente en el búfer y la función regresa casi instantáneamente. En el caso contrario, el hilo de la persona que llama se absorbe hasta que se ocupa el espacio en el búfer (a medida que los mensajes se consumen del otro lado) y luego de eso, el mensaje se escribe y la función se completa. | Si hay suficiente espacio en el buffer del socket, el mensaje se escribe y la función regresa. En el caso contrario, la función regresa inmediatamente sin enviar el mensaje (el envío se puede volver a intentar más tarde) |
¿Aún no has dejado una estrella ? ¡Hazlo ahora;)!
Para crear un servidor TCP de bloqueo clásico, solo necesita crear un objeto tcp::TcpServer :
# include < MinimalSocket/tcp/TcpServer.h >
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< true > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
ábrelo:
// open the server: binds the port and start to listen on the port
bool success = tcp_server.open();
y ahora estás listo para aceptar nuevos clientes:
// accepts the next client that will ask the connection
MinimalSocket::tcp::TcpConnectionBlocking accepted_connection =
tcp_server.acceptNewClient(); // blocking till a client actually asks the
// connection
Ahora puedes intercambiar mensajes con el cliente aceptado simplemente haciendo esto:
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= accepted_connection.receive(message_max_size);
// send a message
accepted_connection.send( " a message to send " );
Si, en cambio, necesita un servidor sin bloqueo, puede crearlo de manera similar:
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< false > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
tcp_server.open();
Esta versión del servidor no será bloqueante, lo que significa que la función de aceptación regresará inmediatamente:
// check if a client asked for the connection. If no, the function immediately
// returns a nullopt. On the contrary, the returned optional contains the
// handler to the connected client
std::optional<MinimalSocket::tcp::TcpConnectionBlocking>
maybe_accepted_connection = tcp_server.acceptNewClient();
Tenga en cuenta que aunque el servidor per se no bloquea, el controlador de cliente finalmente aceptado sí está bloqueando. También puedes convertirlo en un socket sin bloqueo, transfiriendo el socket a un controlador sin bloqueo:
MinimalSocket::tcp::TcpConnectionNonBlocking accepted_connection_nn_block =
maybe_accepted_connection-> turnToNonBlocking ();
Para crear un cliente TCP solo necesita crear un objeto tcp::TcpClient :
# include < MinimalSocket/tcp/TcpClient.h >
MinimalSocket::Port server_port = 15768 ;
std::string server_address = " 192.168.125.85 " ;
MinimalSocket::tcp::TcpClient< true > tcp_client (
MinimalSocket::Address{server_address, server_port});
ábrelo:
// Open the server. Here, the client will ask the connection to specified
// server. After that, the client will be actually connected.
bool success =
tcp_client.open(); // blocking till the connection is actually established
ahora puedes recibir y enviar información con el servidor remoto simplemente haciendo esto:
// send a message
tcp_client.send( " a message to send " );
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= tcp_client.receive(message_max_size);
Si, en cambio, necesita un cliente sin bloqueo, puede crearlo y usarlo de manera similar:
MinimalSocket::Port server_port = 15768 ;
std::string server_address = " 192.168.125.85 " ;
MinimalSocket::tcp::TcpClient< false > tcp_client (
MinimalSocket::Address{server_address, server_port});
tcp_client.open();
std:: size_t message_max_size = 1000 ;
// non blocking receive: returns immediately with an empty message in case no
// new data were available, or with a non empty message in the contrary case
std::string received_message = tcp_client.receive(message_max_size);
Para crear un socket udp normal, sólo necesita crear un objeto udp::Udp :
# include < MinimalSocket/udp/UdpSocket.h >
MinimalSocket::Port this_socket_port = 15768 ;
MinimalSocket::udp::Udp< true > udp_socket (this_socket_port,
MinimalSocket::AddressFamily::IP_V6);
ábrelo:
// Open the server. This will bind the specified port.
bool success = udp_socket.open();
Ahora puedes recibir y enviar información con otros sockets udp :
// send a message to another udp
MinimalSocket::Address other_recipient_udp =
MinimalSocket::Address{ " 192.168.125.85 " , 15768 };
udp_socket.sendTo( " a message to send " , other_recipient_udp);
// receive a message from another udp reaching this one
std:: size_t message_max_size = 1000 ;
auto received_message = udp_socket.receive(message_max_size);
// check the sender address
MinimalSocket::Address other_sender_udp = received_message->sender;
// access the received message
std::string received_message_content // resized to the nunber of bytes
// actually received
= received_message->received_message;
También puede decidir "conectar" un socket udp abierto a una dirección específica. Tenga en cuenta que esto simplemente significa que los mensajes entrantes de otros pares se filtrarán, ya que los sockets udp no están orientados a la conexión:
MinimalSocket::Address permanent_sender_udp =
MinimalSocket::Address{ " 192.168.125.85 " , 15768 };
MinimalSocket::udp::UdpConnected< true > udp_connected_socket =
udp_socket.connect(
permanent_sender_udp); // ownership of the underlying socket is
// transfered from udp_socket to
// udp_connected_socket, meaning that you can't
// use anymore udp_socket (unless you re-open
// it)
Ahora puedes enviar y recibir datos sin tener que especificar el destinatario/remitente:
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= udp_connected_socket.receive(message_max_size);
// send a message
udp_connected_socket.send( " a message to send " );
También puedes crear y utilizar sockets udp sin bloqueo:
MinimalSocket::Port this_socket_port = 15768 ;
MinimalSocket::udp::Udp< false > udp_socket (
this_socket_port, MinimalSocket::AddressFamily::IP_V6);
udp_socket.open();
std:: size_t message_max_size = 1000 ;
// non blocking receive: returns immediately with an empty message in case no
// new data were available, or with a non empty message in the contrary case
//
// struct ReceiveStringResult {
// Address sender;
// std::string received_message;
// };
std::optional<MinimalSocket::ReceiveStringResult> received_message =
udp_socket.receive(message_max_size);
¿Aún no has dejado una estrella ? ¡Hazlo ahora;)!
Aquí se pueden encontrar ejemplos de uso de sockets tcp , mientras que aquí se analizan ejemplos de udp .
¡¡¡ATENCIÓN!!! Es posible que su firewall bloquee la ejecución de las muestras la primera vez: configure correctamente su firewall o ejecute las muestras con privilegios de administrador.
¿Aún no has dejado una estrella ? ¡Hazlo ahora;)!
Para consumir esta biblioteca puede confiar en CMake. Más precisamente, puede recuperar este paquete y vincularlo a la biblioteca MinimalSocket :
include (FetchContent)
set (BUILD_MinimalCppSocket_SAMPLES OFF CACHE BOOL "" FORCE) # you don't want the samples in this case
FetchContent_Declare(
min_sock
GIT_REPOSITORY https://github.com/andreacasalino/Minimal-Socket
GIT_TAG master
)
FetchContent_MakeAvailable(min_sock)
y luego vincular a la biblioteca MinimalSocket :
target_link_libraries ( ${TARGET_NAME}
MinimalSocket
)
Todos los módulos específicos del sistema están incluidos internamente y no están expuestos. Además, en Windows , wsock32 y ws2_32 están vinculados de forma privada y no es necesario vincularlos nuevamente cuando consume MinimalSocket .