MinimalSocket предоставляет вам современную библиотеку C++ для настройки и создания соединений сокетов tcp и udp полностью независимым от платформы способом. Поддерживаемые системы: Windows , любой дистрибутив Linux и MacOS .
В разделе «Функции» подробно описаны различные функции MinimalSocket . Прочтите «Использование и примеры», чтобы узнать, насколько легко использовать MinimalSocket .
Это проект CMake . Проверьте поддержку CMake, чтобы узнать, как можно интегрировать эту библиотеку.
Не забудьте поставить звездочку , если эта библиотека оказалась для вас полезной.
Еще не покинули звезду ? Сделайте это сейчас ;)!
MinimalSocket позволяет создавать и настраивать соединения TCP и UDP . Сообщения можно отправлять и получать как в виде буфера байтов, так и в виде строк. Фактически, это единственная возможность, которая вам нужна для сокета, поскольку более сложные сообщения можно сериализовать в буфер байтов или интернализировать из него, используя, среди прочего, такие подходы, как Google Protocol Buffers или NanoPb.
Вот наиболее примечательные характеристики MinimalSocket :
В этой таблице суммированы различия между блокирующим и неблокирующим поведением сокета, который можно создать с помощью MinimalSocket :
Поведение блокировки: вызывающий абонент блокируется до завершения или истечения времени ожидания (если оно было указано). | Неблокирующее поведение, функции возвращаются немедленно | |
---|---|---|
принятие нового клиента (только TCP) | поток вызывающего абонента поглощается до тех пор, пока новый клиент фактически не попросит подключиться или не истечет время ожидания (если таковое было указано) | если запрос на соединение от клиента уже был поставлен в очередь до вызова функции принятия, возвращается новый обработчик соединения, в противном случае возвращается nullopt. |
получить новое сообщение (tcp и udp) | поток вызывающего абонента поглощается до тех пор, пока в сокет не будет отправлено новое сообщение или не будет достигнут тайм-аут (если таковой был указан) | если сообщение было отправлено и уже поставлено в очередь в буфере сокета до вызова функции приема, это сообщение возвращается, в противном случае возвращается пустое сообщение. |
отправить новое сообщение (tcp и udp) | В случае, если буфер сокета не заполнен и может полностью вместить отправляемое сообщение, сообщение фактически записывается в буфер, и функция завершает работу почти мгновенно. В противном случае поток вызывающего объекта поглощается до тех пор, пока в буфере не будет занято место (поскольку сообщения потребляются с другой стороны), а после этого сообщение фактически записывается и функция завершается. | Если в буфере сокета достаточно места, сообщение записывается и функция завершает работу. В противном случае функция возвращается немедленно, не отправляя сообщение (отправку можно повторить позже). |
Еще не покинули звезду ? Сделайте это сейчас ;)!
Чтобы создать классический блокирующий TCP- сервер, вам просто нужно создать объект 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);
откройте его:
// open the server: binds the port and start to listen on the port
bool success = tcp_server.open();
и теперь вы готовы принимать новых клиентов:
// 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
теперь вы можете обмениваться сообщениями с принятым клиентом, просто выполнив следующее:
// 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 " );
Если вместо этого вам нужен неблокирующий сервер, вы можете создать его аналогичным образом:
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< false > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
tcp_server.open();
Эта версия сервера будет неблокирующей, а это означает, что функция принятия немедленно вернет результат:
// 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();
Обратите внимание: хотя сервер сам по себе не блокируется, в конечном итоге принятый обработчик клиента блокируется. Вы также можете превратить его в неблокирующий сокет, передав сокет неблокирующему обработчику:
MinimalSocket::tcp::TcpConnectionNonBlocking accepted_connection_nn_block =
maybe_accepted_connection-> turnToNonBlocking ();
Чтобы создать TCP- клиент, вам просто нужно создать объект 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});
откройте его:
// 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
теперь вы можете получать и отправлять информацию с удаленного сервера, просто выполнив следующие действия:
// 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);
Если вместо этого вам нужен неблокирующий клиент, вы можете создать его и использовать аналогичным образом:
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);
Чтобы создать обычный сокет udp, вам просто нужно создать объект 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);
откройте его:
// Open the server. This will bind the specified port.
bool success = udp_socket.open();
теперь вы можете получать и отправлять информацию с помощью других сокетов 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;
вы также можете решить «подключить» открытый сокет udp к определенному адресу. Помните, что это просто означает, что сообщения, поступающие от других узлов, будут отфильтровываться, поскольку сокеты udp не ориентированы на соединение:
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)
Теперь вы можете отправлять и получать данные без указания получателя/отправителя:
// 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 " );
Вы также можете создавать и использовать неблокирующие сокеты udp :
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);
Еще не покинули звезду ? Сделайте это сейчас ;)!
Примеры использования TCP- сокетов можно найти здесь, а примеры udp обсуждаются здесь.
ВНИМАНИЕ!!! Выполнение образцов может быть заблокировано в первый раз вашим брандмауэром: правильно настройте брандмауэр или запустите примеры с правами администратора.
Еще не покинули звезду ? Сделайте это сейчас ;)!
Чтобы использовать эту библиотеку, вы можете положиться на CMake. Точнее, вы можете получить этот пакет и связать его с библиотекой 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)
а затем дайте ссылку на библиотеку MinimalSocket :
target_link_libraries ( ${TARGET_NAME}
MinimalSocket
)
Все модули, специфичные для системы, включены внутри и не видны. Более того, в Windows wsock32 и ws2_32 связаны частным образом, и вам не нужно связывать их снова при использовании MinimalSocket .