тайм-аут сокета и удаление опции O_NONBLOCK - PullRequest
1 голос
/ 23 февраля 2011

Я реализовал время ожидания сокета и повторил попытку, но для этого мне пришлось установить сокет как неблокирующий сокет. Тем не менее, мне нужно сокет для блокировки. Это была моя попытка решить эти две проблемы. Это не работает. Последующие отправки звонков блокируют, но никогда не отправляют никаких данных. Когда я подключаюсь без выбора и тайм-аута, последующие вызовы отправляются нормально.

Ссылки:

Код:

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);

Ответы [ 2 ]

1 голос
/ 23 февраля 2011

После того, как вы получите записываемое событие без ошибок, вам нужно снова вызвать connect(), как описано в документации. Он сообщает вам, успешно ли установлено соединение или нет.

0 голосов
/ 23 февраля 2011

Почему бы не использовать опции сокетов SO_RCVTIMEO или SO_SNDTIMEO?Или я что-то упустил в вашем вопросе?

...