MinimalSocket oferece uma biblioteca C++ moderna para configurar e criar conexões de soquete tcp e udp , de uma forma totalmente independente de plataforma. Os sistemas suportados são: Windows , qualquer distribuição Linux e MacOS .
A seção Recursos detalha os vários recursos do MinimalSocket . Leia Uso e exemplos para ver como é fácil usar MinimalSocket .
Este é um projeto CMake , verifique o suporte do CMake para ver como esta biblioteca pode ser integrada.
Lembre-se de deixar uma estrela caso você tenha achado esta biblioteca útil.
Ainda não deixou uma estrela ? Faça agora ;)!
MinimalSocket permite construir e configurar conexões TCP e UDP . As mensagens podem ser enviadas e recebidas em termos de buffer de bytes ou strings. Na verdade, esse é o único recurso necessário para um soquete, já que mensagens mais complexas podem ser serializadas ou internalizadas a partir de um buffer de bytes usando, entre outras, abordagens como Google Protocol Buffers ou NanoPb.
Estas são as características mais notáveis do MinimalSocket :
Esta tabela resume as diferenças entre os comportamentos de bloqueio e não bloqueio do soquete que podem ser criados usando MinimalSocket :
Comportamento de bloqueio, o chamador é bloqueado até a conclusão ou o tempo limite ser atingido (se algum tiver sido especificado) | Comportamento sem bloqueio, as funções retornam imediatamente | |
---|---|---|
aceitação de um novo cliente (somente tcp) | o thread do chamador é absorvido até que um novo cliente realmente peça para se conectar ou o tempo limite seja atingido (se algum tiver sido especificado) | se uma solicitação de conexão de um cliente já estava na fila antes de chamar a função de aceitação, um novo manipulador de conexão será retornado, caso contrário, um nullopt será retornado. |
receber uma nova mensagem (tcp e udp) | thread do chamador é absorvido até que uma nova mensagem seja enviada para o soquete ou o tempo limite seja atingido (se algum tiver sido especificado) | se uma mensagem foi enviada e já enfileirada no buffer do soquete antes de chamar a função de recebimento, essa mensagem será retornada, caso contrário, uma mensagem vazia será retornada. |
enviar uma nova mensagem (tcp e udp) | Caso o buffer do soquete não esteja cheio e possa hospedar inteiramente a mensagem a ser enviada, a mensagem é realmente escrita no buffer e a função retorna quase instantaneamente. No caso contrário, o thread do chamador é absorvido até que o espaço no buffer seja esgotado (conforme as mensagens são consumidas do outro lado) e depois disso a mensagem é realmente escrita e a função é concluída. | Se houver espaço suficiente no buffer do soquete, a mensagem é escrita e a função retorna. Caso contrário, a função retorna imediatamente sem realmente enviar a mensagem (o envio pode ser repetido mais tarde) |
Ainda não deixou uma estrela ? Faça agora ;)!
Para criar um servidor tcp de bloqueio clássico você só precisa construir um 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);
abra-o:
// open the server: binds the port and start to listen on the port
bool success = tcp_server.open();
e agora você está pronto para aceitar novos 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
agora você pode trocar mensagens com o cliente aceito simplesmente fazendo isto:
// 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 " );
Se você precisar de um servidor sem bloqueio, poderá criá-lo de maneira semelhante:
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< false > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
tcp_server.open();
Esta versão do servidor não será bloqueadora, o que significa que a função de aceitação retornará imediatamente:
// 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();
Observe que mesmo que o servidor em si não esteja bloqueando, o manipulador de cliente eventualmente aceito está bloqueando. Você também pode transformá-lo em um soquete sem bloqueio, transferindo o soquete para um manipulador sem bloqueio:
MinimalSocket::tcp::TcpConnectionNonBlocking accepted_connection_nn_block =
maybe_accepted_connection-> turnToNonBlocking ();
Para criar um cliente tcp você só precisa construir um 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});
abra-o:
// 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
agora você pode receber e enviar informações com o servidor remoto simplesmente fazendo o seguinte:
// 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);
Se você precisar de um cliente sem bloqueio, poderá criá-lo e usá-lo de maneira semelhante:
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 criar um soquete udp normal você só precisa construir um 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);
abra-o:
// Open the server. This will bind the specified port.
bool success = udp_socket.open();
agora você pode receber e enviar informações com outros soquetes 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;
você também pode decidir "conectar" um soquete UDP aberto a um endereço específico. Esteja ciente de que isso significa simplesmente que as mensagens recebidas de outros pares serão filtradas, pois os soquetes udp não são orientados à conexão:
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)
Agora você pode enviar e receber dados sem precisar especificar o destinatário/remetente:
// 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 " );
Você também pode criar e usar soquetes UDP sem bloqueio:
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);
Ainda não deixou uma estrela ? Faça agora ;)!
Exemplos de uso sobre soquetes tcp podem ser encontrados aqui, enquanto exemplos de udp são discutidos aqui.
ATENÇÃO!!! A execução dos exemplos pode ser bloqueada na primeira vez pelo seu firewall: configure corretamente o seu firewall ou execute os exemplos com privilégios de administrador
Ainda não deixou uma estrela ? Faça agora ;)!
Para consumir esta biblioteca você pode contar com o CMake. Mais precisamente, você pode buscar este pacote e vincular à 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)
e, em seguida, vincule à biblioteca MinimalSocket :
target_link_libraries ( ${TARGET_NAME}
MinimalSocket
)
Todos os módulos específicos do sistema estão incluídos internamente e não estão expostos. Além disso, no Windows , wsock32 e ws2_32 estão vinculados de forma privada e você não precisa vinculá-los novamente ao consumir MinimalSocket .