tests: udp (partial) + added a few functions to udp handle
This commit is contained in:
parent
c98083164f
commit
bef8bd1d5c
104
src/uvw/udp.hpp
104
src/uvw/udp.hpp
@ -315,6 +315,28 @@ public:
|
||||
req->send(get(), reinterpret_cast<const sockaddr *>(&addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
* Note that if the socket has not previously been bound with `bind()`, it
|
||||
* will be bound to `0.0.0.0` (the _all interfaces_ IPv4 address) and a
|
||||
* random port number.
|
||||
*
|
||||
* The handle takes the ownership of the data and it is in charge of delete
|
||||
* them.
|
||||
*
|
||||
* A SendEvent event will be emitted when the data have been sent.<br/>
|
||||
* An ErrorEvent event will be emitted in case of errors.
|
||||
*
|
||||
* @param addr A valid instance of Addr.
|
||||
* @param data The data to be sent.
|
||||
* @param len The lenght of the submitted data.
|
||||
*/
|
||||
template<typename I = IPv4>
|
||||
void send(Addr addr, std::unique_ptr<char[]> data, std::size_t len) {
|
||||
send<I>(addr.ip, addr.port, std::move(data), len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
@ -353,6 +375,28 @@ public:
|
||||
req->send(get(), reinterpret_cast<const sockaddr *>(&addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
* Note that if the socket has not previously been bound with `bind()`, it
|
||||
* will be bound to `0.0.0.0` (the _all interfaces_ IPv4 address) and a
|
||||
* random port number.
|
||||
*
|
||||
* The handle doesn't take the ownership of the data. Be sure that their
|
||||
* lifetime overcome the one of the request.
|
||||
*
|
||||
* A SendEvent event will be emitted when the data have been sent.<br/>
|
||||
* An ErrorEvent event will be emitted in case of errors.
|
||||
*
|
||||
* @param addr A valid instance of Addr.
|
||||
* @param data The data to be sent.
|
||||
* @param len The lenght of the submitted data.
|
||||
*/
|
||||
template<typename I = IPv4>
|
||||
void send(Addr addr, char *data, std::size_t len) {
|
||||
send<I>(addr.ip, addr.port, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
@ -381,6 +425,66 @@ public:
|
||||
return bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
* Same as `send()`, but it won’t queue a send request if it can’t be
|
||||
* completed immediately.
|
||||
*
|
||||
* @param addr A valid instance of Addr.
|
||||
* @param data The data to be sent.
|
||||
* @param len The lenght of the submitted data.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
template<typename I = IPv4>
|
||||
int trySend(Addr addr, std::unique_ptr<char[]> data, std::size_t len) {
|
||||
return trySend<I>(addr.ip, addr.port, std::move(data), len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
* Same as `send()`, but it won’t queue a send request if it can’t be
|
||||
* completed immediately.
|
||||
*
|
||||
* @param ip The address to which to send data.
|
||||
* @param port The port to which to send data.
|
||||
* @param data The data to be sent.
|
||||
* @param len The lenght of the submitted data.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
template<typename I = IPv4>
|
||||
int trySend(std::string ip, unsigned int port, char *data, std::size_t len) {
|
||||
typename details::IpTraits<I>::Type addr;
|
||||
details::IpTraits<I>::addrFunc(ip.data(), port, &addr);
|
||||
|
||||
uv_buf_t bufs[] = { uv_buf_init(data, len) };
|
||||
auto bw = uv_udp_try_send(get(), bufs, 1, reinterpret_cast<const sockaddr *>(&addr));
|
||||
|
||||
if(bw < 0) {
|
||||
publish(ErrorEvent{bw});
|
||||
bw = 0;
|
||||
}
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the UDP socket.
|
||||
*
|
||||
* Same as `send()`, but it won’t queue a send request if it can’t be
|
||||
* completed immediately.
|
||||
*
|
||||
* @param addr A valid instance of Addr.
|
||||
* @param data The data to be sent.
|
||||
* @param len The lenght of the submitted data.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
template<typename I = IPv4>
|
||||
int trySend(Addr addr, char *data, std::size_t len) {
|
||||
return trySend<I>(addr.ip, addr.port, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for receiving data.
|
||||
*
|
||||
|
||||
@ -47,6 +47,7 @@ set(TARGET_RESOURCE resource)
|
||||
set(TARGET_SIGNAL signal)
|
||||
set(TARGET_TCP tcp)
|
||||
set(TARGET_TIMER timer)
|
||||
set(TARGET_UDP udp)
|
||||
set(TARGET_UTIL util)
|
||||
set(TARGET_WORK work)
|
||||
|
||||
@ -183,6 +184,14 @@ target_include_directories(${TARGET_TIMER} PRIVATE ${COMMON_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_TIMER} PRIVATE ${COMMON_LINK_LIBS})
|
||||
add_test(NAME ${TARGET_TIMER} COMMAND ${TARGET_TIMER})
|
||||
|
||||
# Test TARGET_UDP
|
||||
|
||||
set(TARGET_UDP_SOURCES $<TARGET_OBJECTS:odr> uvw/udp.cpp)
|
||||
add_executable(${TARGET_UDP} ${TARGET_UDP_SOURCES})
|
||||
target_include_directories(${TARGET_UDP} PRIVATE ${COMMON_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_UDP} PRIVATE ${COMMON_LINK_LIBS})
|
||||
add_test(NAME ${TARGET_UDP} COMMAND ${TARGET_UDP})
|
||||
|
||||
# Test TARGET_UTIL
|
||||
|
||||
set(TARGET_UTIL_SOURCES $<TARGET_OBJECTS:odr> uvw/util.cpp)
|
||||
|
||||
103
test/uvw/udp.cpp
Normal file
103
test/uvw/udp.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <uvw.hpp>
|
||||
|
||||
|
||||
TEST(Udp, Functionalities) {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
auto handle = loop->resource<uvw::UDPHandle>();
|
||||
|
||||
ASSERT_FALSE(handle->multicastMembership("0.0.0.0", "127.0.0.1", uvw::UDPHandle::Membership::JOIN_GROUP));
|
||||
ASSERT_TRUE(handle->multicastMembership("224.0.0.1", "127.0.0.1", uvw::UDPHandle::Membership::JOIN_GROUP));
|
||||
ASSERT_TRUE(handle->multicastMembership("224.0.0.1", "127.0.0.1", uvw::UDPHandle::Membership::LEAVE_GROUP));
|
||||
ASSERT_TRUE(handle->multicastLoop(true));
|
||||
ASSERT_TRUE(handle->multicastTtl(42));
|
||||
ASSERT_TRUE(handle->multicastInterface("127.0.0.1"));
|
||||
ASSERT_TRUE(handle->broadcast(true));
|
||||
ASSERT_TRUE(handle->ttl(42));
|
||||
ASSERT_FALSE(handle->ttl(0));
|
||||
|
||||
handle->close();
|
||||
loop->run();
|
||||
}
|
||||
|
||||
|
||||
TEST(Udp, BindRecvStop) {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
auto handle = loop->resource<uvw::UDPHandle>();
|
||||
|
||||
handle->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
|
||||
handle->bind("127.0.0.1", 4242);
|
||||
handle->recv();
|
||||
handle->stop();
|
||||
handle->close();
|
||||
|
||||
loop->run();
|
||||
}
|
||||
|
||||
|
||||
TEST(Udp, ReadTrySend) {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
auto server = loop->resource<uvw::UDPHandle>();
|
||||
auto client = loop->resource<uvw::UDPHandle>();
|
||||
|
||||
server->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
client->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
|
||||
server->once<uvw::UDPDataEvent>([&client](const uvw::UDPDataEvent &, uvw::UDPHandle &handle) {
|
||||
client->close();
|
||||
handle.close();
|
||||
});
|
||||
|
||||
server->bind("127.0.0.1", 4242);
|
||||
server->recv();
|
||||
|
||||
auto dataTrySend = std::unique_ptr<char[]>(new char[1]{ 'a' });
|
||||
client->trySend("127.0.0.1", 4242, std::move(dataTrySend), 1);
|
||||
|
||||
loop->run();
|
||||
}
|
||||
|
||||
|
||||
TEST(Udp, ReadSend) {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
auto server = loop->resource<uvw::UDPHandle>();
|
||||
auto client = loop->resource<uvw::UDPHandle>();
|
||||
|
||||
server->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
client->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
|
||||
server->once<uvw::UDPDataEvent>([](const uvw::UDPDataEvent &, uvw::UDPHandle &handle) {
|
||||
handle.close();
|
||||
});
|
||||
|
||||
client->once<uvw::SendEvent>([](const uvw::SendEvent &, uvw::UDPHandle &handle) {
|
||||
handle.close();
|
||||
});
|
||||
|
||||
server->bind("127.0.0.1", 4242);
|
||||
server->recv();
|
||||
|
||||
auto dataSend = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });
|
||||
client->send(uvw::Addr{ "127.0.0.1", 4242 }, std::move(dataSend), 1);
|
||||
|
||||
loop->run();
|
||||
}
|
||||
|
||||
|
||||
TEST(Udp, Sock) {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
auto handle = loop->resource<uvw::UDPHandle>();
|
||||
|
||||
handle->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
|
||||
|
||||
handle->bind("127.0.0.1", 4242);
|
||||
handle->recv();
|
||||
|
||||
uvw::Addr sock = handle->sock();
|
||||
ASSERT_EQ(sock.ip, "127.0.0.1");
|
||||
ASSERT_EQ(sock.port, decltype(sock.port){4242});
|
||||
|
||||
handle->close();
|
||||
loop->run();
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user