3#include "DesktopSocket.h"
6#include "SignalHandler.h"
10class EthernetServer :
public Server {
13 SocketHandle server_fd = INVALID_SOCKET_HANDLE;
14 struct sockaddr_in server_addr;
15 int _status = wl_status_t::WL_DISCONNECTED;
16 bool is_blocking =
false;
17 bool _noDelay =
false;
19 static std::vector<EthernetServer*>& active_servers() {
20 static std::vector<EthernetServer*> servers;
23 static void cleanupAll(
int) {
24 for (
auto* server : active_servers()) {
25 if (server && server->server_fd != INVALID_SOCKET_HANDLE) {
26 shutdown(server->server_fd, SHUT_RDWR);
27 closeSocket(server->server_fd);
28 server->server_fd = INVALID_SOCKET_HANDLE;
34 EthernetServer(
int port = 80) : _port(port) {
35 static bool signal_registered =
false;
36 if (!signal_registered) {
37 SignalHandler::registerHandler(SIGINT, cleanupAll);
38 SignalHandler::registerHandler(SIGTERM, cleanupAll);
39 signal_registered =
true;
44 auto& servers = active_servers();
45 auto it = std::find(servers.begin(), servers.end(),
this);
46 if (it != servers.end()) servers.erase(it);
49 void begin() { begin(_port); }
50 void begin(
int port) { begin_(port); }
52 if (server_fd != INVALID_SOCKET_HANDLE) {
53 struct linger linger_opt = {1, 0};
54 setsockopt(server_fd, SOL_SOCKET, SO_LINGER,
55 reinterpret_cast<const char*
>(&linger_opt),
sizeof(linger_opt));
56 shutdown(server_fd, SHUT_RDWR);
57 closeSocket(server_fd);
59 server_fd = INVALID_SOCKET_HANDLE;
60 _status = wl_status_t::WL_DISCONNECTED;
63 WiFiClient available(uint8_t* =
nullptr) {
return available_(); }
64 size_t write(uint8_t ch)
override {
return write(&ch, 1); }
65 size_t write(
const uint8_t* buf,
size_t size)
override {
66 int rc = ::send(server_fd,
reinterpret_cast<const char*
>(buf),
static_cast<int>(size), 0);
67 return rc < 0 ? 0 : rc;
69 int status() {
return _status; }
70 void setNoDelay(
bool nodelay) { _noDelay = nodelay; }
71 bool getNoDelay() {
return _noDelay; }
73 if (server_fd == INVALID_SOCKET_HANDLE)
return false;
76 pfd.events = POLLRDNORM;
77 return WSAPoll(&pfd, 1, 0) > 0 && (pfd.revents & POLLRDNORM);
82 bool begin_(
int port = 0) {
83 if (port > 0) _port = port;
84 _status = wl_status_t::WL_DISCONNECTED;
85 ensureSocketRuntime();
86 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET_HANDLE) {
87 _status = wl_status_t::WL_CONNECT_FAILED;
91 setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR,
92 reinterpret_cast<const char*
>(&option),
sizeof(option));
93 server_addr.sin_family = AF_INET;
94 server_addr.sin_addr.s_addr = INADDR_ANY;
95 server_addr.sin_port = htons(_port);
96 while (::bind(server_fd,
reinterpret_cast<struct sockaddr*
>(&server_addr),
97 sizeof(server_addr)) < 0) {
98 Logger.error(
"bind failed");
101 if (::listen(server_fd, 10) < 0) {
102 _status = wl_status_t::WL_CONNECT_FAILED;
103 Logger.error(
"listen failed");
107 active_servers().push_back(
this);
108 _status = wl_status_t::WL_CONNECTED;
111 void setBlocking(
bool flag) { is_blocking = flag; }
113 EthernetClient available_() {
114 struct sockaddr_in client_addr;
115 SocketLength client_addr_len =
sizeof(client_addr);
116 SocketHandle client_fd;
117 if (_status == wl_status_t::WL_CONNECT_FAILED) begin(_port);
120 pfd.events = POLLRDNORM;
121 int poll_rc = WSAPoll(&pfd, 1, 200);
122 if (!is_blocking && (poll_rc <= 0 || !(pfd.revents & POLLRDNORM)))
123 return EthernetClient(
nullptr);
124 if ((client_fd = ::accept(server_fd,
reinterpret_cast<struct sockaddr*
>(&client_addr),
125 &client_addr_len)) == INVALID_SOCKET_HANDLE) {
126 Logger.error(
"accept failed");
127 return EthernetClient(
nullptr);
129 setSocketNonBlocking(client_fd);
130 return EthernetClient(std::make_shared<SocketImpl>(client_fd, &client_addr));
We provide the WiFi class to simulate the Arduino WIFI. In in Linux we can expect that networking is ...
Definition CanMsg.cpp:31
EthernetClient WiFiClient
Alias for EthernetClient to provide WiFiClient compatibility.
Definition WiFiClient.h:28