transport: fix a issue for connect

when set connect timeout, the timeout is invalid
This commit is contained in:
xutao 2021-01-08 15:44:07 +08:00
parent 3dc41ff14c
commit b1a4b24963

View File

@ -78,14 +78,67 @@ static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...", // Set socket to non-blocking
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port); int flags;
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) { if ((flags = fcntl(tcp->sock, F_GETFL, NULL)) < 0) {
close(tcp->sock); ESP_LOGE(TAG, "[sock=%d] get file flags error: %s", tcp->sock, strerror(errno));
tcp->sock = -1; goto error;
return -1; }
if (fcntl(tcp->sock, F_SETFL, flags |= O_NONBLOCK) < 0) {
ESP_LOGE(TAG, "[sock=%d] set nonblocking error: %s", tcp->sock, strerror(errno));
goto error;
}
ESP_LOGD(TAG, "[sock=%d] Connecting to server. IP: %s, Port: %d",
tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) < 0) {
if (errno == EINPROGRESS) {
fd_set fdset;
esp_transport_utils_ms_to_timeval(timeout_ms, &tv);
FD_ZERO(&fdset);
FD_SET(tcp->sock, &fdset);
int res = select(tcp->sock+1, NULL, &fdset, NULL, &tv);
if (res < 0) {
ESP_LOGE(TAG, "[sock=%d] select() error: %s", tcp->sock, strerror(errno));
goto error;
}
else if (res == 0) {
ESP_LOGE(TAG, "[sock=%d] select() timeout", tcp->sock);
goto error;
} else {
int sockerr;
socklen_t len = (socklen_t)sizeof(int);
if (getsockopt(tcp->sock, SOL_SOCKET, SO_ERROR, (void*)(&sockerr), &len) < 0) {
ESP_LOGE(TAG, "[sock=%d] getsockopt() error: %s", tcp->sock, strerror(errno));
goto error;
}
else if (sockerr) {
ESP_LOGE(TAG, "[sock=%d] delayed connect error: %s", tcp->sock, strerror(sockerr));
goto error;
}
}
} else {
ESP_LOGE(TAG, "[sock=%d] connect() error: %s", tcp->sock, strerror(errno));
goto error;
}
}
// Reset socket to blocking
if ((flags = fcntl(tcp->sock, F_GETFL, NULL)) < 0) {
ESP_LOGE(TAG, "[sock=%d] get file flags error: %s", tcp->sock, strerror(errno));
goto error;
}
if (fcntl(tcp->sock, F_SETFL, flags & ~O_NONBLOCK) < 0) {
ESP_LOGE(TAG, "[sock=%d] reset blocking error: %s", tcp->sock, strerror(errno));
goto error;
} }
return tcp->sock; return tcp->sock;
error:
close(tcp->sock);
tcp->sock = -1;
return -1;
} }
static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms) static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)