Hello,
I implemented a socket timeout and retry but in order to do it I had to set the socket as a non-blocking socket. However, I need the socket to block. This was my attempt at a solution to these two problems. This is not working. Subsequent send calls block but never send any data. When I connect without the select and the timeout, subsequent send calls work normally.
References:
C: socket connection timeout
How to reset a socket back to blocking mode (after I set it to nonblocking mode)?
Code:
fd_set fdset;
struct timeval tv;
fcntl(dsock, F_SETFL, O_NONBLOCK);
tv.tv_sec = theDeviceTimeout;
tv.tv_usec = 0;
int retries=0;
logi(theLogOutput, LOG_INFO, "connecting to device socket num retrys: %i", theDeviceRetry);
for(retries=0;retries<theDeviceRetry;retries++) {
connect(dsock, (struct sockaddr *)&daddr, sizeof daddr);
FD_ZERO(&fdset);
FD_SET(dsock, &fdset);
if (select(dsock + 1, NULL, &fdset, NULL, &tv) == 1) {
int so_error;
socklen_t slen = sizeof so_error;
getsockopt(dsock, SOL_SOCKET, SO_ERROR, &so_error, &slen);
if (so_error == 0) {
logi(theLogOutput, LOG_INFO, "connected to socket on port %i on %s", theDevicePort, theDeviceIP);
break;
} else {
logi(theLogOutput, LOG_WARN, "connect to %i failed on ip %s because %s retries %i", theDevicePort, theDeviceIP, strerror(errno), retries);
logi(theLogOutput, LOG_WARN, "failed to connect to device %s", strerror(errno));
logi(theLogOutput, LOG_WARN, "error: %i %s", so_error, strerror(so_error));
continue;
}
}
}
int opts;
opts = fcntl(dsock,F_GETFL);
logi(theLogOutput, LOG_DEBUG, "clearing nonblock option %i retries %i", opts, retries);
opts ^= O_NONBLOCK;
fcntl(dsock, F_SETFL, opts);