refactoring
This commit is contained in:
parent
7d486b3755
commit
10f0f1336b
13
README.md
13
README.md
@ -26,7 +26,7 @@ void listen(uvw::Loop &loop) {
|
|||||||
client->read();
|
client->read();
|
||||||
});
|
});
|
||||||
|
|
||||||
tcp->bind<uvw::Tcp::IPv4>("127.0.0.1", 4242);
|
tcp->bind("127.0.0.1", 4242);
|
||||||
tcp->listen();
|
tcp->listen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ void conn(uvw::Loop &loop) {
|
|||||||
tcp.close();
|
tcp.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
tcp->connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 4242);
|
tcp->connect(std::string{"127.0.0.1"}, 4242);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@ -147,7 +147,7 @@ To know what are the available resources' types, please refer the API reference.
|
|||||||
##### The event-based approach
|
##### The event-based approach
|
||||||
|
|
||||||
For `uvw` offers an event-based approach, resources are small event emitters to which listeners can be attached.
|
For `uvw` offers an event-based approach, resources are small event emitters to which listeners can be attached.
|
||||||
Attaching a listener to a resource is the reccomended way to be notified about changes.
|
Attaching a listener to a resource is the recommended way to be notified about changes.
|
||||||
Listeners must be callable objects of type `void(const EventType &, ResourceType &)`, where:
|
Listeners must be callable objects of type `void(const EventType &, ResourceType &)`, where:
|
||||||
|
|
||||||
* `EventType` is the type of the event for which they have been designed
|
* `EventType` is the type of the event for which they have been designed
|
||||||
@ -180,11 +180,14 @@ tcp->on<uvw::ListenEvent>([](const uvw::ListenEvent &event, uvw::Tcp &srv) mutab
|
|||||||
client->read();
|
client->read();
|
||||||
});
|
});
|
||||||
|
|
||||||
tcp->bind<uvw::Tcp::IPv4>("127.0.0.1", 4242);
|
tcp->bind("127.0.0.1", 4242);
|
||||||
tcp->listen();
|
tcp->listen();
|
||||||
```
|
```
|
||||||
|
|
||||||
The API reference is the reccomended documentation for further details about resources and their methods.
|
Note that `uvw::Tcp` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind<uvw::Tcp::IPv4>("127.0.0.1", 4242)`.
|
||||||
|
It's suffice to explicitly specify `uvw::Tcp::IPv6` as the underlying protocol to use it.
|
||||||
|
|
||||||
|
The API reference is the recommended documentation for further details about resources and their methods.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|||||||
@ -126,7 +126,10 @@ public:
|
|||||||
listen(DEFAULT_BACKLOG);
|
listen(DEFAULT_BACKLOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void accept(T &) = 0;
|
template<typename U>
|
||||||
|
void accept(U &ref) {
|
||||||
|
this->invoke(&uv_accept, this->template get<uv_stream_t>(), ref.template get<uv_stream_t>());
|
||||||
|
}
|
||||||
|
|
||||||
void read() {
|
void read() {
|
||||||
this->invoke(&uv_read_start, this->template get<uv_stream_t>(), &this->allocCallback, &readCallback);
|
this->invoke(&uv_read_start, this->template get<uv_stream_t>(), &this->allocCallback, &readCallback);
|
||||||
|
|||||||
@ -17,23 +17,8 @@ namespace uvw {
|
|||||||
|
|
||||||
|
|
||||||
class Tcp final: public Stream<Tcp> {
|
class Tcp final: public Stream<Tcp> {
|
||||||
using SockFunctionType = Addr(*)(const Tcp &);
|
|
||||||
using PeerFunctionType = SockFunctionType;
|
|
||||||
|
|
||||||
template<typename I>
|
|
||||||
static Addr tSock(const Tcp &tcp) noexcept {
|
|
||||||
return details::address<I>(uv_tcp_getsockname, tcp.get<uv_tcp_t>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename I>
|
|
||||||
static Addr tPeer(const Tcp &tcp) noexcept {
|
|
||||||
return details::address<I>(uv_tcp_getpeername, tcp.get<uv_tcp_t>());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Tcp(std::shared_ptr<Loop> ref)
|
explicit Tcp(std::shared_ptr<Loop> ref)
|
||||||
: Stream{HandleType<uv_tcp_t>{}, std::move(ref)},
|
: Stream{HandleType<uv_tcp_t>{}, std::move(ref)}
|
||||||
sockF{&tSock<details::IPv4>},
|
|
||||||
peerF{&tPeer<details::IPv4>}
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -61,33 +46,34 @@ public:
|
|||||||
invoke(&uv_tcp_keepalive, get<uv_tcp_t>(), enable, time.count());
|
invoke(&uv_tcp_keepalive, get<uv_tcp_t>(), enable, time.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void bind(std::string ip, unsigned int port, Flags<Bind> flags = Flags<Bind>{}) {
|
void bind(std::string ip, unsigned int port, Flags<Bind> flags = Flags<Bind>{}) {
|
||||||
typename Traits::Type addr;
|
typename details::IpTraits<I>::Type addr;
|
||||||
Traits::AddrFunc(ip.data(), port, &addr);
|
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
|
||||||
|
invoke(&uv_tcp_bind, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags);
|
||||||
if(0 == invoke(&uv_tcp_bind, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags)) {
|
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void bind(Addr addr, Flags<Bind> flags = Flags<Bind>{}) {
|
void bind(Addr addr, Flags<Bind> flags = Flags<Bind>{}) {
|
||||||
bind<I>(addr.ip, addr.port, flags);
|
bind<I>(addr.ip, addr.port, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr sock() const noexcept { return sockF(*this); }
|
template<typename I = IPv4>
|
||||||
Addr peer() const noexcept { return peerF(*this); }
|
Addr sock() const noexcept {
|
||||||
|
return details::address<I>(&uv_tcp_getsockname, get<uv_tcp_t>());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
|
Addr peer() const noexcept {
|
||||||
|
return details::address<I>(&uv_tcp_getpeername, get<uv_tcp_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename I = IPv4>
|
||||||
void connect(std::string ip, unsigned int port) {
|
void connect(std::string ip, unsigned int port) {
|
||||||
typename Traits::Type addr;
|
typename details::IpTraits<I>::Type addr;
|
||||||
Traits::AddrFunc(ip.data(), port, &addr);
|
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
|
||||||
|
|
||||||
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Connect &) {
|
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Connect &) {
|
||||||
ptr->sockF = &tSock<I>;
|
|
||||||
ptr->peerF = &tPeer<I>;
|
|
||||||
ptr->publish(event);
|
ptr->publish(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,19 +83,8 @@ public:
|
|||||||
connect->connect(&uv_tcp_connect, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr));
|
connect->connect(&uv_tcp_connect, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void connect(Addr addr) { connect<I>(addr.ip, addr.port); }
|
void connect(Addr addr) { connect<I>(addr.ip, addr.port); }
|
||||||
|
|
||||||
void accept(Tcp &tcp) override {
|
|
||||||
if(0 == invoke(&uv_accept, get<uv_stream_t>(), tcp.get<uv_stream_t>())) {
|
|
||||||
tcp.sockF = sockF;
|
|
||||||
tcp.peerF = peerF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SockFunctionType sockF;
|
|
||||||
PeerFunctionType peerF;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -39,40 +39,27 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
class Udp final: public Handle<Udp> {
|
class Udp final: public Handle<Udp> {
|
||||||
using SockFunctionType = Addr(*)(const Udp &);
|
|
||||||
using PeerFunctionType = Addr(*)(const sockaddr *);
|
|
||||||
|
|
||||||
template<typename I>
|
|
||||||
static Addr tSock(const Udp &udp) noexcept {
|
|
||||||
return details::address<I>(uv_udp_getsockname, udp.get<uv_udp_t>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
|
||||||
static Addr tPeer(const sockaddr *addr) noexcept {
|
|
||||||
const typename Traits::Type *aptr = reinterpret_cast<const typename Traits::Type *>(addr);
|
|
||||||
int len = sizeof(*addr);
|
|
||||||
return details::address<I>(aptr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Udp(std::shared_ptr<Loop> ref)
|
explicit Udp(std::shared_ptr<Loop> ref)
|
||||||
: Handle{HandleType<uv_udp_t>{}, std::move(ref)},
|
: Handle{HandleType<uv_udp_t>{}, std::move(ref)}
|
||||||
sockF{&tSock<details::IPv4>},
|
|
||||||
peerF{&tPeer<details::IPv4>}
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
template<typename I>
|
||||||
static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) {
|
static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) {
|
||||||
|
typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr);
|
||||||
|
int len = sizeof(*addr);
|
||||||
|
|
||||||
Udp &udp = *(static_cast<Udp*>(handle->data));
|
Udp &udp = *(static_cast<Udp*>(handle->data));
|
||||||
// data will be destroyed no matter of what the value of nread is
|
// data will be destroyed no matter of what the value of nread is
|
||||||
std::unique_ptr<const char[]> data{buf->base};
|
std::unique_ptr<const char[]> data{buf->base};
|
||||||
|
|
||||||
if(nread > 0) {
|
if(nread > 0) {
|
||||||
// data available (can be truncated)
|
// data available (can be truncated)
|
||||||
udp.publish(UDPDataEvent{udp.peerF(addr), std::move(data), nread, flags & UV_UDP_PARTIAL});
|
udp.publish(UDPDataEvent{details::address<I>(aptr, len), std::move(data), nread, flags & UV_UDP_PARTIAL});
|
||||||
} else if(nread == 0 && addr == nullptr) {
|
} else if(nread == 0 && addr == nullptr) {
|
||||||
// no more data to be read, doing nothing is fine
|
// no more data to be read, doing nothing is fine
|
||||||
} else if(nread == 0 && addr != nullptr) {
|
} else if(nread == 0 && addr != nullptr) {
|
||||||
// empty udp packet
|
// empty udp packet
|
||||||
udp.publish(UDPDataEvent{udp.peerF(addr), std::move(data), nread, false});
|
udp.publish(UDPDataEvent{details::address<I>(aptr, len), std::move(data), nread, false});
|
||||||
} else {
|
} else {
|
||||||
// transmission error
|
// transmission error
|
||||||
udp.publish(ErrorEvent(nread));
|
udp.publish(ErrorEvent(nread));
|
||||||
@ -100,30 +87,26 @@ public:
|
|||||||
|
|
||||||
bool init() { return initialize<uv_udp_t>(&uv_udp_init); }
|
bool init() { return initialize<uv_udp_t>(&uv_udp_init); }
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void bind(std::string ip, unsigned int port, Flags<Bind> flags = Flags<Bind>{}) {
|
void bind(std::string ip, unsigned int port, Flags<Bind> flags = Flags<Bind>{}) {
|
||||||
typename Traits::Type addr;
|
typename details::IpTraits<I>::Type addr;
|
||||||
Traits::AddrFunc(ip.data(), port, &addr);
|
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
|
||||||
|
invoke(&uv_udp_bind, get<uv_udp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags);
|
||||||
if(0 == invoke(&uv_udp_bind, get<uv_udp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags)) {
|
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void bind(Addr addr, Flags<Bind> flags = Flags<Bind>{}) {
|
void bind(Addr addr, Flags<Bind> flags = Flags<Bind>{}) {
|
||||||
bind<I>(addr.ip, addr.port, flags);
|
bind<I>(addr.ip, addr.port, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr sock() const noexcept { return sockF(*this); }
|
template<typename I = IPv4>
|
||||||
|
Addr sock() const noexcept {
|
||||||
template<typename I>
|
return details::address<I>(&uv_udp_getsockname, get<uv_udp_t>());
|
||||||
void multicastMembership(std::string multicast, std::string interface, Membership membership) {
|
|
||||||
if(0 == invoke(&uv_udp_set_membership, get<uv_udp_t>(), multicast.data(), interface.data(), static_cast<uv_membership>(membership))) {
|
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename I = IPv4>
|
||||||
|
void multicastMembership(std::string multicast, std::string interface, Membership membership) {
|
||||||
|
invoke(&uv_udp_set_membership, get<uv_udp_t>(), multicast.data(), interface.data(), static_cast<uv_membership>(membership));
|
||||||
}
|
}
|
||||||
|
|
||||||
void multicastLoop(bool enable = true) {
|
void multicastLoop(bool enable = true) {
|
||||||
@ -134,27 +117,22 @@ public:
|
|||||||
invoke(&uv_udp_set_multicast_ttl, get<uv_udp_t>(), val > 255 ? 255 : val);
|
invoke(&uv_udp_set_multicast_ttl, get<uv_udp_t>(), val > 255 ? 255 : val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I>
|
template<typename I = IPv4>
|
||||||
void multicastInterface(std::string interface) {
|
void multicastInterface(std::string interface) {
|
||||||
if(0 == invoke(&uv_udp_set_multicast_interface, get<uv_udp_t>(), interface.data())) {
|
invoke(&uv_udp_set_multicast_interface, get<uv_udp_t>(), interface.data());
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast(bool enable = false) { invoke(&uv_udp_set_broadcast, get<uv_udp_t>(), enable); }
|
void broadcast(bool enable = false) { invoke(&uv_udp_set_broadcast, get<uv_udp_t>(), enable); }
|
||||||
void ttl(int val) { invoke(&uv_udp_set_ttl, get<uv_udp_t>(), val > 255 ? 255 : val); }
|
void ttl(int val) { invoke(&uv_udp_set_ttl, get<uv_udp_t>(), val > 255 ? 255 : val); }
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void send(std::string ip, unsigned int port, char *data, ssize_t len) {
|
void send(std::string ip, unsigned int port, char *data, ssize_t len) {
|
||||||
typename Traits::Type addr;
|
typename details::IpTraits<I>::Type addr;
|
||||||
Traits::AddrFunc(ip.data(), port, &addr);
|
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
|
||||||
|
|
||||||
uv_buf_t bufs[] = { uv_buf_init(data, len) };
|
uv_buf_t bufs[] = { uv_buf_init(data, len) };
|
||||||
|
|
||||||
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Send &) {
|
auto listener = [ptr = this->shared_from_this()](const auto &event, details::Send &) {
|
||||||
ptr->sockF = &tSock<I>;
|
|
||||||
ptr->peerF = &tPeer<I>;
|
|
||||||
ptr->publish(event);
|
ptr->publish(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,20 +140,17 @@ public:
|
|||||||
send->once<ErrorEvent>(listener);
|
send->once<ErrorEvent>(listener);
|
||||||
send->once<SendEvent>(listener);
|
send->once<SendEvent>(listener);
|
||||||
send->send(get<uv_udp_t>(), bufs, 1, reinterpret_cast<const sockaddr *>(&addr));
|
send->send(get<uv_udp_t>(), bufs, 1, reinterpret_cast<const sockaddr *>(&addr));
|
||||||
|
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
void send(std::string ip, unsigned int port, std::unique_ptr<char[]> data, ssize_t len) {
|
void send(std::string ip, unsigned int port, std::unique_ptr<char[]> data, ssize_t len) {
|
||||||
send<I>(ip, port, data.get(), len);
|
send<I>(ip, port, data.get(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
int trySend(std::string ip, unsigned int port, char *data, ssize_t len) {
|
int trySend(std::string ip, unsigned int port, char *data, ssize_t len) {
|
||||||
typename Traits::Type addr;
|
typename details::IpTraits<I>::Type addr;
|
||||||
Traits::AddrFunc(ip.data(), port, &addr);
|
details::IpTraits<I>::AddrFunc(ip.data(), port, &addr);
|
||||||
|
|
||||||
uv_buf_t bufs[] = { uv_buf_init(data, len) };
|
uv_buf_t bufs[] = { uv_buf_init(data, len) };
|
||||||
auto bw = uv_udp_try_send(get<uv_udp_t>(), bufs, 1, reinterpret_cast<const sockaddr *>(&addr));
|
auto bw = uv_udp_try_send(get<uv_udp_t>(), bufs, 1, reinterpret_cast<const sockaddr *>(&addr));
|
||||||
@ -183,25 +158,22 @@ public:
|
|||||||
if(bw < 0) {
|
if(bw < 0) {
|
||||||
this->publish(ErrorEvent{bw});
|
this->publish(ErrorEvent{bw});
|
||||||
bw = 0;
|
bw = 0;
|
||||||
} else {
|
|
||||||
sockF = &tSock<I>;
|
|
||||||
peerF = &tPeer<I>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bw;
|
return bw;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I = IPv4>
|
||||||
int trySend(std::string ip, unsigned int port, std::unique_ptr<char[]> data, ssize_t len) {
|
int trySend(std::string ip, unsigned int port, std::unique_ptr<char[]> data, ssize_t len) {
|
||||||
return trySend<I>(ip, port, data.get(), len);
|
return trySend<I>(ip, port, data.get(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recv() { invoke(&uv_udp_recv_start, get<uv_udp_t>(), &allocCallback, &recvCallback); }
|
template<typename I = IPv4>
|
||||||
void stop() { invoke(&uv_udp_recv_stop, get<uv_udp_t>()); }
|
void recv() {
|
||||||
|
invoke(&uv_udp_recv_start, get<uv_udp_t>(), &allocCallback, &recvCallback<I>);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
void stop() { invoke(&uv_udp_recv_stop, get<uv_udp_t>()); }
|
||||||
SockFunctionType sockF;
|
|
||||||
PeerFunctionType peerF;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -107,12 +107,12 @@ const IpTraits<IPv4>::NameFuncType IpTraits<IPv4>::NameFunc = &uv_ip4_name;
|
|||||||
const IpTraits<IPv6>::NameFuncType IpTraits<IPv6>::NameFunc = &uv_ip6_name;
|
const IpTraits<IPv6>::NameFuncType IpTraits<IPv6>::NameFunc = &uv_ip6_name;
|
||||||
|
|
||||||
|
|
||||||
template<typename I, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I>
|
||||||
Addr address(const typename Traits::Type *aptr, int len) noexcept {
|
Addr address(const typename details::IpTraits<I>::Type *aptr, int len) noexcept {
|
||||||
std::pair<std::string, unsigned int> addr{};
|
std::pair<std::string, unsigned int> addr{};
|
||||||
char name[len];
|
char name[len];
|
||||||
|
|
||||||
int err = Traits::NameFunc(aptr, name, len);
|
int err = details::IpTraits<I>::NameFunc(aptr, name, len);
|
||||||
|
|
||||||
if(0 == err) {
|
if(0 == err) {
|
||||||
addr = { std::string{name}, ntohs(aptr->sin_port) };
|
addr = { std::string{name}, ntohs(aptr->sin_port) };
|
||||||
@ -126,7 +126,7 @@ Addr address(const typename Traits::Type *aptr, int len) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename I, typename F, typename H, typename..., typename Traits = details::IpTraits<I>>
|
template<typename I, typename F, typename H>
|
||||||
Addr address(F &&f, const H *handle) noexcept {
|
Addr address(F &&f, const H *handle) noexcept {
|
||||||
sockaddr_storage ssto;
|
sockaddr_storage ssto;
|
||||||
int len = sizeof(ssto);
|
int len = sizeof(ssto);
|
||||||
@ -135,7 +135,7 @@ Addr address(F &&f, const H *handle) noexcept {
|
|||||||
int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
|
int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
|
||||||
|
|
||||||
if(0 == err) {
|
if(0 == err) {
|
||||||
typename Traits::Type *aptr = reinterpret_cast<typename Traits::Type *>(&ssto);
|
typename details::IpTraits<I>::Type *aptr = reinterpret_cast<typename details::IpTraits<I>::Type *>(&ssto);
|
||||||
addr = address<I>(aptr, len);
|
addr = address<I>(aptr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@ void listen(uvw::Loop &loop) {
|
|||||||
std::cout << "close" << std::endl;
|
std::cout << "close" << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
tcp->bind<uvw::Tcp::IPv4>("127.0.0.1", 4242);
|
tcp->bind("127.0.0.1", 4242);
|
||||||
tcp->listen();
|
tcp->listen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ void conn(uvw::Loop &loop) {
|
|||||||
std::cout << "close" << std::endl;
|
std::cout << "close" << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
tcp->connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 4242);
|
tcp->connect(std::string{"127.0.0.1"}, 4242);
|
||||||
}
|
}
|
||||||
|
|
||||||
void g() {
|
void g() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user