Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.07.2012, 15:20   #1
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Добрый день. Столкнулся с такой проблемой. Опрашиваю через сокеты более 1000 устройств на открытый порт (23). Если открыт, то беру нужную инфу, если закрыт то в логи записываю, что устройство недоступно. Но если оно не доступно, то connect висит 15 сек, а мне на опрос необходимо потратить не более 5 сек или до устройства потери (в локалке). На каждое устройство создается своя нить, т.е. опрашиваются они одновременно.
Гугл перерыл. Не могу найти timeout на connect. Нашел только select на send и recv, но до них же приконнектится надо. Помогите найти решение, люди добрые, пожалуйста. Спасибо.

Нашел ответ. Перед вызовом блокируем сокет с помощью ioctlsocket. Далее вызываем connect. Далее установка тайма:
Код:
        struct timeval tv;
	tv.tv_sec = 5;  // указываем время в секундах
	tv.tv_usec = 0;
	FD_ZERO(&fds);
	FD_SET(s, &fds);
	end = select(s + 1, NULL, &fds, NULL, &tv);
end = 0 - нет подключения
1 - коннект установился

Вот код. Только до коннекта. В общем то пишу для себя, но думаю пригодится. Не забыл и ссылку, откуда взял инфу.

Код:
int _tmain(int argc, _TCHAR* argv[])
{
	// http://www.linux.org.ru/forum/development/3745084

	int			s;
	struct sockaddr_in	addr;
	fd_set			fds;
	struct timeval		tv;
	int rets;

	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == -1)
		return 0;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(80);
	int retur;
	addr.sin_addr.s_addr = inet_addr("10.11.0.3"); /* google.com */
	unsigned long iMode = 1;

	int iResult = ioctlsocket(s, FIONBIO, &iMode);

	if ((retur = connect(s, (const struct sockaddr *) &addr, sizeof(addr)) == -1) < 0) {
		printf("connect");
		return 0;
	}

	/* Wait for connection. */
	tv.tv_sec = 5;
	tv.tv_usec = 0;
	FD_ZERO(&fds);
	FD_SET(s, &fds);
	rets = select(s + 1, NULL, &fds, NULL, &tv);


	return 0;
}

Последний раз редактировалось Stilet; 22.07.2012 в 17:34.
Tahoma вне форума Ответить с цитированием
Старый 22.07.2012, 17:51   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

select работает и с сокетами, которые находятся в состонии connect-a - по завершению connect сокет будет доступен для записи (ну или соотственно ошибочка будет), так что не надо блокировать сокет. Таймаут в принципе можно задать но как он будет работать все на милость того, кто сделал TCP стек. Легче самому подождать какоето время, после наступления которого закрыть сокеты, которые не законектились.
waleri вне форума Ответить с цитированием
Старый 22.07.2012, 20:30   #3
Rock-n-Rolla
Форумчанин
 
Регистрация: 11.01.2012
Сообщений: 178
По умолчанию

рекомендую использовать WSAConnect и все подобные ей WSA-функции. в MSDN всё подробно задокументировано. они всё сразу сделано так что можно их использовать как асинхронные функции
progromore.i2p - первый русскоязычный портал программистов в скрытосети
Rock-n-Rolla вне форума Ответить с цитированием
Старый 23.07.2012, 10:01   #4
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Для WSAConnect нужен обработчик. Мне же необходима линейность.

waleri, да с timeout при блокировке может быть ошибочно опознан открытый сокет, если timeout ниже того времени, что необходимо для создания подключения. Но в моем случае 5сек должно хватить, т.к. все оборудование находится в локалке и ответ свыше 5 сек просто не должен быть.
Tahoma вне форума Ответить с цитированием
Старый 23.07.2012, 10:35   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Я только сказал, что
а) Не нужно блокировать сокет, а можно (и даже нужно) использовать select.
б) Лучше не рассчитывать на встроейнный таймаут, но это как говорится, кому как.
А будет ли таймаут 5сек, 15сек или 50сек это дело хозяйское.
waleri вне форума Ответить с цитированием
Старый 23.07.2012, 19:44   #6
Rock-n-Rolla
Форумчанин
 
Регистрация: 11.01.2012
Сообщений: 178
По умолчанию

Цитата:
Сообщение от Tahoma Посмотреть сообщение
Для WSAConnect нужен обработчик. Мне же необходима линейность.
вы читать-то умеете? какой ещё обработчик? не нужно никаких обработчиков. вызываем функцию WSAConnect в неблокирующем режиме, ждём 5 сек, если коннекта не произошло, то отменяем операцию.
progromore.i2p - первый русскоязычный портал программистов в скрытосети
Rock-n-Rolla вне форума Ответить с цитированием
Старый 24.07.2012, 08:51   #7
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Попробую все варианты. Выберу наиболее быстрый и отказоустойчевый. Спасибо за подсказки.
Tahoma вне форума Ответить с цитированием
Старый 25.07.2012, 22:45   #8
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Я только сказал, что
а) Не нужно блокировать сокет, а можно (и даже нужно) использовать select.
б) Лучше не рассчитывать на встроейнный таймаут, но это как говорится, кому как.
А будет ли таймаут 5сек, 15сек или 50сек это дело хозяйское.
По "а" немного не понял. Если я не заблокирую сокет, то connect длится установленное по умолчанию время и уже потом доходит до select. Если же select выставлять раньше, то конечно же все подключения с ошибками, ведь ему не от чего ждать ответа. По UDP протоколу может и получилось бы.

Последний раз редактировалось Tahoma; 25.07.2012 в 22:51.
Tahoma вне форума Ответить с цитированием
Старый 26.07.2012, 09:17   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Мы не сходились на термине "блокировать" с точностью до наоборот
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка Connect timeout ramzes777 Работа с сетью в Delphi 3 10.10.2014 10:26
Timeout палит скрипт stdio Свободное общение 0 16.02.2012 22:33
Если Connect timeout, то... ramzes777 Работа с сетью в Delphi 3 11.11.2011 16:36
Контроль Timeout в idhttp seet09 Работа с сетью в Delphi 3 26.06.2010 23:54
ClientSocket и TimeOut Powerfull100 Работа с сетью в Delphi 0 22.10.2009 12:29