3#if !defined(USE_ESP32) && !defined(USE_ESP8266) && !defined(USE_RP2040) && !defined(USE_LIBRETINY) && \
4 (defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || defined(USE_SOCKET_IMPL_BSD_SOCKETS))
13static const char *
const TAG =
"async_tcp";
17static constexpr size_t READ_BUFFER_SIZE = 1460;
20 if (connected_ || connecting_) {
21 ESP_LOGW(TAG,
"Already connected/connecting");
29 ESP_LOGE(TAG,
"Invalid address: %s", host);
31 error_cb_(error_arg_,
this, -1);
36 int family = ((
struct sockaddr *) &addr)->sa_family;
39 ESP_LOGE(TAG,
"Failed to create socket");
41 error_cb_(error_arg_,
this, -1);
52 connect_cb_(connect_arg_,
this);
55 if (errno != EINPROGRESS) {
56 ESP_LOGE(TAG,
"Connect failed: %d", errno);
59 error_cb_(error_arg_,
this, errno);
69 bool was_connected = connected_;
72 if (was_connected && disconnect_cb_)
73 disconnect_cb_(disconnect_arg_,
this);
77 if (!socket_ || !connected_)
82 if (errno != EAGAIN && errno != EWOULDBLOCK) {
83 ESP_LOGE(TAG,
"Write error: %d", errno);
86 error_cb_(error_arg_,
this, errno);
103 int fd = socket_->
get_fd();
105 ESP_LOGW(TAG,
"Invalid socket fd");
112 FD_SET(fd, &writefds);
114 struct timeval tv = {0, 0};
115 int ret = select(fd + 1,
nullptr, &writefds,
nullptr, &tv);
117 if (ret > 0 && FD_ISSET(fd, &writefds)) {
120 if (socket_->
getsockopt(SOL_SOCKET, SO_ERROR, &error, &
len) == 0 && error == 0) {
124 connect_cb_(connect_arg_,
this);
126 ESP_LOGW(TAG,
"Connection failed: %d", error);
129 error_cb_(error_arg_,
this, error);
131 }
else if (ret < 0) {
132 ESP_LOGE(TAG,
"Select error: %d", errno);
135 error_cb_(error_arg_,
this, errno);
137 }
else if (connected_) {
139 if (!socket_->
ready())
142 uint8_t buf[READ_BUFFER_SIZE];
146 ESP_LOGI(TAG,
"Connection closed by peer");
148 }
else if (
len > 0) {
150 data_cb_(data_arg_,
this, buf,
len);
151 }
else if (errno != EAGAIN && errno != EWOULDBLOCK) {
152 ESP_LOGW(TAG,
"Read error: %d", errno);
155 error_cb_(error_arg_,
this, errno);
bool connect(const char *host, uint16_t port)
size_t write(const char *data, size_t len)
virtual ssize_t write(const void *buf, size_t len)=0
virtual int setblocking(bool blocking)=0
virtual ssize_t read(void *buf, size_t len)=0
virtual int getsockopt(int level, int optname, void *optval, socklen_t *optlen)=0
virtual int get_fd() const
Get the underlying file descriptor (returns -1 if not supported)
virtual int connect(const struct sockaddr *addr, socklen_t addrlen)=0
virtual bool ready() const
Check if socket has data ready to read For loop-monitored sockets, checks with the Application's sele...
socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::string &ip_address, uint16_t port)
Set a sockaddr to the specified address and port for the IP version used by socket_ip().
std::unique_ptr< Socket > socket_loop_monitored(int domain, int type, int protocol)
Create a socket and monitor it for data in the main loop.