6#include <Poco/Net/StreamSocket.h>
7#include <Poco/Net/ServerSocket.h>
8#include <Poco/Net/SocketAddress.h>
9#include <Poco/Net/NetException.h>
10#include <Poco/Net/SocketDefs.h>
11#include <Poco/Timespan.h>
24 stream_ = std::move(sock);
25 connected_ = stream_ !=
nullptr;
28 peer_ = stream_->peerAddress().toString();
44 std::lock_guard<std::mutex> lock(acceptMu_);
45 accepted_.push_back(std::move(sock));
49 std::lock_guard<std::mutex> lock(acceptMu_);
50 if (accepted_.empty())
return false;
51 out = std::move(accepted_.front());
52 accepted_.erase(accepted_.begin());
57 if (!net_ || !net_->
worker())
return false;
64 auto sock = std::make_unique<Poco::Net::StreamSocket>();
65 int timeoutMs = self->net_->getTimeout();
66 sock->connect(Poco::Net::SocketAddress(host, port),
67 Poco::Timespan(timeoutMs / 1000, (timeoutMs % 1000) * 1000));
68 sock->setBlocking(
false);
69 self->setConnectedSocket(std::move(sock));
72 c.peer = self->getPeer();
73 self->net_->post(std::move(
c));
74 self->net_->watchTcp(self);
75 }
catch (
const Poco::Net::ConnectionRefusedException&) {
78 self->net_->post(std::move(
c));
84 self->net_->post(std::move(fail));
85 }
catch (
const Poco::Exception& ex) {
87 std::string msg = ex.displayText();
88 if (msg.find(
"timed") != std::string::npos || msg.find(
"Timeout") != std::string::npos)
90 else if (msg.find(
"host") != std::string::npos || msg.find(
"DNS") != std::string::npos)
94 self->net_->post(std::move(
c));
100 self->net_->post(std::move(fail));
108 server_ = std::make_unique<Poco::Net::ServerSocket>(port);
109 server_->setBlocking(
false);
121 c.reason =
"refused";
122 net_->
post(std::move(
c));
129 std::unique_ptr<TcpSocket> sock;
131 return sock.release();
135 if (!
data || !net_)
return false;
136 size_t n =
data->getSize();
141 if (
s.empty())
return false;
147 if (!
d ||
n == 0)
return false;
148 const char*
p =
static_cast<const char*
>(
d);
149 bool overLimit =
false;
151 std::lock_guard<std::mutex> lock(sendMu_);
153 if (!overLimit) pendingSend_.insert(pendingSend_.end(),
p,
p +
n);
161 if (net_) net_->
post(std::move(
c));
168 std::lock_guard<std::mutex> lock(sendMu_);
169 return pendingSend_.size();
173 std::lock_guard<std::mutex> lock(sendMu_);
174 pendingSend_.clear();
178 if (!stream_ || !connected_)
return;
180 std::vector<char> local;
182 std::lock_guard<std::mutex> lock(sendMu_);
183 if (pendingSend_.empty())
return;
184 local.swap(pendingSend_);
189 while (off < local.size()) {
191 int n = stream_->sendBytes(local.data() +
static_cast<long>(off),
192 static_cast<int>(local.size() - off));
194 off +=
static_cast<size_t>(
n);
195 }
catch (
const Poco::TimeoutException&) {
197 }
catch (
const Poco::IOException& e) {
200 if (e.code() == POCO_EWOULDBLOCK || e.code() == POCO_EAGAIN)
break;
209 if (failed && net_) {
215 net_->
post(std::move(
c));
219 if (!failed && off < local.size()) {
220 std::lock_guard<std::mutex> lock(sendMu_);
221 pendingSend_.insert(pendingSend_.begin(),
222 local.begin() +
static_cast<long>(off),
233 if (stream_) stream_->close();
238 if (server_) server_->close();
245 return connected_ && stream_ !=
nullptr;
254 if (server_)
return static_cast<uint16_t
>(server_->address().port());
255 if (stream_)
return static_cast<uint16_t
>(stream_->address().port());
In-memory byte buffer implementing eve::Data (ref-counted).
void submit(std::function< void()> job)
Queues an arbitrary blocking job to run on the worker thread.
Network module: TCP/UDP/HTTP factories, background worker, and completion event plumbing....
void watchTcp(TcpSocket *sock)
Internal: register/unregister sockets for pump polling.
NetWorker * worker() const
Background worker thread handle (advanced).
void unwatchTcp(TcpSocket *sock)
void post(NetCompletion c)
Posts a completion to the worker queue (thread-safe).
TCP socket backed by Poco::Net; supports both client (connect) and server (listen/accept) roles....
void pushAccepted(std::unique_ptr< TcpSocket > sock)
bool listen(uint16_t port)
Starts listening on the given port; true on success.
bool takeAccepted(std::unique_ptr< TcpSocket > &out)
Poco::Net::StreamSocket * stream()
uint16_t getLocalPort() const
Local listening port, or 0.
bool queueSend(const void *d, size_t n)
Append bytes to the pending send queue (worker-thread flush via pollSockets).
bool sendString(std::string s)
Sends a string payload.
TcpSocket(Network *net)
Creates an unconnected socket owned by the given module.
void setConnectedSocket(std::unique_ptr< Poco::Net::StreamSocket > sock)
void close()
Closes the socket.
void flushSend()
Push pending bytes onto the socket; called from Network::pollSockets.
std::string getPeer() const
Remote peer address string, e.g. "1.2.3.4:5678".
Poco::Net::ServerSocket * server()
size_t pendingSendBytes() const
Internal: queued-outgoing byte counter for back-pressure.
TcpSocket * accept()
Accepts one pending client, or nullptr if none.
bool isConnected() const
True while a stream is connected.
bool connect(std::string host, uint16_t port)
Connects to host:port; true on success.
bool send(eve::data::ByteData *data)
Sends a framed byte payload; true when queued/accepted.
constexpr size_t kMaxSendBuffer
Maximum outgoing send buffer size per socket (1 MiB).
One asynchronous network result/event. handle points at the originating TcpSocket/UdpSocket/HttpReque...