Тайм-аут сокета в C ++ Linux - PullRequest
8 голосов
/ 01 июня 2009

Хорошо, прежде всего я хотел бы упомянуть, что я делаю это совершенно этично, и да, я сканирую порт.

Программа работает нормально, когда порт открыт, но когда я добираюсь до закрытого сокета, программа останавливается на очень долгое время, потому что нет условия ожидания. Ниже приведен следующий код

int main(){

    int err, net;
    struct hostent *host;
    struct sockaddr_in sa;

    sa.sin_family = AF_INET;

    sa.sin_port = htons(xxxx);
    sa.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");

    net = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    err = connect(net, (struct sockaddr *)&sa, sizeof(sa));

    if(err >= 0){ cout << "Port is Open"; }
    else { cout << "Port is Closed"; }

}

Я обнаружил это при переполнении стека, но для меня это не имеет смысла, используя команду select () .

Вопрос в том, можем ли мы сделать тайм-аут функции connect (), чтобы не ждать год, чтобы он вернулся с ошибкой?

Ответы [ 3 ]

7 голосов
/ 01 июня 2009

Самое простое - настроить alarm и прервать connect сигналом (см. UNP 14.2):


signal( SIGALRM, connect_alarm ); /* connect_alarm is you signal handler */
alarm( secs ); /* secs is your timeout in seconds */
if ( connect( fs, addr, addrlen ) < 0 )
{
    if ( errno == EINTR ) /* timeout */
        ...
}
alarm( 0 ); /* cancel alarm */

Хотя использование select не намного сложнее:)
Возможно, вы захотите узнать и о raw sockets .

2 голосов
/ 01 июня 2009

Если вы не можете использовать блокирующий ввод-вывод для этого, вам следует изучить вызов setsockopt (), в частности флаг SO_SNDTIMEO (или другие флаги, в зависимости от вашей ОС).

Будьте предупреждены, эти флаги не являются надежными / переносимыми и могут быть реализованы по-разному на разных платформах или в разных версиях данной платформы.

Традиционный / лучший способ сделать это - неблокирующий подход, использующий select (). Если вы не знакомы с сокетами, одна из лучших книг - «Иллюстрированный протокол TCP / IP», том 1: «Протоколы». Это на Amazon в: http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

1 голос
/ 06 июля 2009

RudeSocket решил проблему

Я нашел файл lib, протестированный в linux Fedora (не уверен насчет Windows), который дает мне возможность ожидания Ниже вы можете найти очень простой пример.

#include <rude/socket.h>
#include <iostream>

using namespace std;
using namespace rude;

Socket soc;
soc.setTimeout(30, 5);

//Try connecting
if (soc.connect("xxx.xxx.xxx.xxx", 80)){

    cout << "Connected to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
}

//connections Failed
else{
    cout << "Timeout to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
}

soc.close();

Вот ссылка на DevSite

...