У меня есть существующее многопоточное приложение, которое использует блокирующий вызов connect ().
Однако я хочу ввести время ожидания подключения для приложения, когда, если сервер не ответит на наш запрос в течение x миллисекунд, приложение прекратит попытки и выдаст ошибку.
Однако я не могувыяснить, как сделать это с помощью опроса.
@ caf неблокирующее соединение с использованием select очень помогло. Но я читал, что select медленнее по сравнению с опросом, поэтому я хочу использовать опрос.Не могли бы вы сказать мне, если это правда?
Я вставляю его код из сообщения здесь
int main(int argc, char **argv) {
u_short port; /* user specified port number */
char *addr; /* will be a pointer to the address */
struct sockaddr_in address; /* the libc network address data structure */
short int sock = -1; /* file descriptor for the network socket */
fd_set fdset;
struct timeval tv;
if (argc != 3) {
fprintf(stderr, "Usage %s <port_num> <address>\n", argv[0]);
return EXIT_FAILURE;
}
port = atoi(argv[1]);
addr = argv[2];
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(addr); /* assign the address */
address.sin_port = htons(port); /* translate int2port num */
sock = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);
connect(sock, (struct sockaddr *)&address, sizeof(address));
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 10; /* 10 second timeout */
tv.tv_usec = 0;
if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error == 0) {
printf("%s:%d is open\n", addr, port);
}
}
close(sock);
return 0;
}
Не могли бы вы помочь мне написать аналогичный функционал с помощью опроса.
Я нахожусь на RHEL и использую версию gcc 4.5.x.
Обновление: для текущего кода как изменить сокет в режим блокировки, как только приложение создает соединения с сервером.Я не могу найти способ снять этот O_NONBLOCK. Обновление 2: fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) & ~O_NONBLOCK);
В одном сообщении указано, что мы можем сделать это с помощью приведенной выше команды.Хотя не получил логин.