ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

подвисает wininet
  #1  
Старый 24.08.2007, 10:58
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию подвисает wininet

вот есть такой код получающий страницы по winnet,
зачастую после вывода строки HttpOpenRequest Successfull перед функцией HttpSendRequest программа подвисает на несколько минут, либо очень надолго, можно ли сделать какой-нибудь таймаут для этих ф-й или как можно получать страницу с таймаутом?

Код:
char* getpage(char* userag,char* proxy, char* url, char* document, char* referer)
{
	char  szData[1500];
	DWORD dwBytesRead;
	
	HINTERNET hInternet = ::InternetOpen(userag, INTERNET_OPEN_TYPE_PROXY, proxy,NULL,0);
	

	if (hInternet != NULL) 
	{
		puts("internetOpen successfull");
		
		HINTERNET hConnect =::InternetConnect(hInternet, url, INTERNET_DEFAULT_HTTP_PORT, NULL,NULL, INTERNET_SERVICE_HTTP,0,1u);

		if (hConnect != NULL) {
				puts("internetConnect successfull");
			
		        HINTERNET hRequest =::HttpOpenRequest(hConnect, TEXT("GET"), document, NULL, referer, 0, INTERNET_FLAG_KEEP_CONNECTION, 1);

			if (hRequest != NULL) {
					puts("HttpOpenRequest successfull");
		//вот тут подвисает иногда!!!					BOOL bSend = ::HttpSendRequest(hRequest, NULL,0, NULL,0);
				if (bSend) {
					puts("httpSendRequest successfull");
					
					BOOL bRead = ::InternetReadFile(hRequest, szData,sizeof(szData)-1, &dwBytesRead);
					if (bRead == FALSE  ||  dwBytesRead == 0)
					{
						puts("error readFile");
						return 0;
					}
					
					szData[dwBytesRead] = 0;
					return szData;
				}

				
				::InternetCloseHandle(hRequest);
			}

		
			::InternetCloseHandle(hConnect);
		}
		
		/
		::InternetCloseHandle(hInternet);
	}


return 0;
}

Последний раз редактировалось Satell; 24.08.2007 в 11:11..
 
Ответить с цитированием

  #2  
Старый 24.08.2007, 15:52
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

как запихать ёё в отдельный поток?
 
Ответить с цитированием

  #3  
Старый 24.08.2007, 16:31
Аватар для NetMan
NetMan
Участник форума
Регистрация: 09.02.2004
Сообщений: 122
Провел на форуме:
1089794

Репутация: 134
По умолчанию

1) Делай структуру, содержащую из:
char* userag, char* proxy, char* url, char* document, char* referer
2) Заполни эту структуру
3) Создавай поток и передавай указатель на эту структуру (см. CreateThread)
 
Ответить с цитированием

  #4  
Старый 24.08.2007, 19:57
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

у меня там ещё таймер есть, а getpage вызвается из обработчика события таймера в цикле, что тогда конкретно в потоке запускать? может есть где простой иходничек работы с потоками? а что происходит в том случае, если код в потоках ещё не отпработал, а наступает следующее событие таймера, например код в каком-то потоке не может получить страницу и подвис, этот код уничтожется или эти недоработавшие потоки будут висеть где-то в памяти?
а сам по себе таймер не создает отдельные потоки случайно?

int CALLBACK TimerProc(void)
{

for (int j=0; j<numsites; j++)
{

//поток должен создаваться гдето тут?!!!
pagedata=getpage(...);
//действия с pagedata

//ещё два раза
getpage(...);
getpage(...);
//поток должен заканчиваться гдето тут!!!

}

}
 
Ответить с цитированием

  #5  
Старый 25.08.2007, 14:46
Аватар для NetMan
NetMan
Участник форума
Регистрация: 09.02.2004
Сообщений: 122
Провел на форуме:
1089794

Репутация: 134
По умолчанию

Цитата:
Сообщение от Satell  
у меня там ещё таймер есть, а getpage вызвается из обработчика события таймера в цикле, что тогда конкретно в потоке запускать?
Можешь, например, создавать отдельный поток для каждой страницы.
Цитата:
Сообщение от Satell  
а что происходит в том случае, если код в потоках ещё не отпработал, а наступает следующее событие таймера, например код в каком-то потоке не может получить страницу и подвис, этот код уничтожется или эти недоработавшие потоки будут висеть где-то в памяти?
Таймер отдельно работает, потоки тоже отдельно. Следовательно недоработавшие потоки будут дорабатывать.
 
Ответить с цитированием

  #6  
Старый 30.08.2007, 23:24
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

делаю потоки таким образом с таймаутом 5 сек, виснуть перестало, но иногда возникает такое, что пропадает связь на модеме (нельзя открыть ничего в броузере) и все идет в таймаут "Can not connect to server" ровно раз в 5 сек, пока не завершишь программу, перегрузка какая-то чтоли, по идее все потоки должны завершаться через 5 сек, всё ли правильно в программе? а как сделать чтобы потоки работали параллельно несколько или они и так работают, но почему тогда puts(pThreadParm->url); выводит ровно раз в 5 сек...

Код:
DWORD WINAPI WorkerFunction( LPVOID );

typedef struct
{
       char* url;
	...структура данных для рабочей функции
} PARM;

int num=0;

DWORD WINAPI WorkerFunction(IN LPVOID vThreadParm)
//vThreadParm - points to PARM passed to thread
{
       PARM* pThreadParm;
       // Initialize local pointer to void pointer passed to thread
       pThreadParm = (PARM*)vThreadParm;
       
       ...тут обрабатывающий код
      puts(pThreadParm->url);

       return 0;
}


int main(int argc, char* argv[])
{
DWORD   dwTimeout;
PARM    threadParm;

HANDLE   hThread; 
DWORD    dwThreadID;


for (int j=0; j<num; j++)
{
hThread = CreateThread(
                     NULL,            // Pointer to thread security attributes 
                     0,               // Initial thread stack size, in bytes 
                     WorkerFunction,  // Pointer to thread function 
                     &threadParm,     // The argument for the new thread
                     0,               // Creation flags 
                     &dwThreadID      // Pointer to returned thread identifier 
                 );    

dwTimeout = 5000; // in milliseconds

if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
           cout << "Can not connect to server";
}

CloseHandle (hThread);
}
}
 
Ответить с цитированием

  #7  
Старый 31.08.2007, 11:17
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

в WorkerFunction вызывается getpage (см. первое сообщение), которая часто подвешивается, WaitForSingleObject ждёт 5 сек и потом по идее должна завершать поток, я думал это делает CloseHandle (hThread), но она этого не делает!!! копиться много потоков, пока не сожрут все ресурсы системы, как грамотно завершить поток?

Код:
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
           cout << "Can not connect to server";
           ExitThread(dwThreadID);       //при её использование тут программа просто виснет
           TerminateThread(hThread,0); // говорят некорректно освобождает ресурсы, в общем все ресурсы системы все равно сжираются, 
хотя потоков кажется меньше создаётся
                                              
}

Последний раз редактировалось Satell; 31.08.2007 в 11:23..
 
Ответить с цитированием

  #8  
Старый 31.08.2007, 15:18
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

HINTERNET hInternet;
HINTERNET hConnect;
HINTERNET hRequest;
объявляю глобально

потом
Код:
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
           cout << "Can not connect to server";
           InternetCloseHandle(hInternet);
           InternetCloseHandle(hConnect);
           InternetCloseHandle(hRequest);     
           WaitForSingleObject ( hThread, INFINITE );     
}
так вот фиг, потоки все равно не завершаются при закрытии дескрипторов ф-й winapi(
виснет похоже HttpSendRequest и как повиснет так вместе с потоком и висит и ничего с ней не поделаешь, а если не ждать WaitForSingleObject ( hThread, INFINITE ); тогда число потоков постоянно растет... почему никто не придумал таймауты для ф-й winapi?

Последний раз редактировалось Satell; 31.08.2007 в 18:39..
 
Ответить с цитированием

  #9  
Старый 31.08.2007, 15:49
Аватар для Ni0x
Ni0x
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
Провел на форуме:
2009677

Репутация: 472
По умолчанию

Люди, ну вы хотябы прежде чем писать многопоточные приложения, прочитайте про эту самую многопоточность.
Цитата:
Функция WaitForSingleObject() приостанавливает выполнение потока до тех пор, пока не произойдет одно из двух событий:

- истечет таймаут ожидания;

- ожидаемый объект перейдет в сигнальное (signaled) состояние.

По возвращаемому значению можно понять, какое из двух событий произошло. Ожидать с помощью wait-функций можно большинство объектов ядра, например, объект "процесс" или "поток", чтобы определить, когда они завершат свою работу.
http://uinc.ru/articles/38/
Надеюсь хоть что-то прояснишь для себя.
 
Ответить с цитированием

  #10  
Старый 31.08.2007, 16:35
Аватар для Satell
Satell
Познающий
Регистрация: 13.01.2007
Сообщений: 78
Провел на форуме:
65872

Репутация: 10
По умолчанию

ну да я жду тут пока поток завершиться, а он не завершается, виснет ф-я HttpSendrequest и висит вместе с потоком, так их накапливается очень много, если не ждать
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
WinInet.. поиск файлов на FTP gevara Реверсинг 5 15.03.2007 12:42



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ