|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
23.09.2007, 22:45 | #1 |
Пользователь
Регистрация: 02.02.2007
Сообщений: 32
|
Подвисание программы
При написании программ на indy в некоторых случаях происходит подвисание интерфейса, он просто замораживается, как избежать такого?
P.S. Компонент idAntiFrize почему-то не работает, проверено горьким опытом. Если можно отвечайте подробнее. |
24.09.2007, 09:52 | #2 |
Старожил
Регистрация: 13.12.2006
Сообщений: 3,859
|
Ну собственно причина может быть в нескольких направленияхзависящих именно от Indy и не зависящих именно от Indy %)
1. Если ты не поленился и почитал первую тему раздела, то ты должен знать, что Indy использует принципе "блокирующих сокетов" точнее этот принцип используется в самой ОС. Что такое принцип блокирующих сокетов? Это понятие означает, что в момент отправки запроса по сети ( с использованием сокета) программа не продолжит свою работу, пока не получит ответа. Собственно это основная причина "зависания" программ. Да, для "обхода" этого не самого приятного факта был написан компонент idAntiFrize, который признан имитировать принцип "неблокирующих" сокетов, релизованный в операционных системах *nix. На самом деле этот компонент разумеется не позволяет тебе работать именно с неблокирующими сокетами, а лишь имитирует это (всего лишь с помощью дополнительных потоков). Но абсолютно не обязательно что это тебе поможет. Зачастую диагностируются подобные ошибки очень просто: если программа "зависла" при работе с сетью, то Indy после того как пройдет время "тайм-аут"-а (которое зависит от каждого протокола в отдельности, описано в RFC соответствующего протокола, а в большинстве случаев Time-out настраивается в самом компоненте Indy), Indy вернет тебе ответ сервера (или ошибку). 2-й вариант причины "зависания" описывать бесполезно, ибо это может быть что угодно. Вобщем если это тебе не помогло, то выкладывай код, посмотрим.
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи |
24.09.2007, 14:22 | #3 | |
Пользователь
Регистрация: 02.02.2007
Сообщений: 32
|
Цитата:
Код в общем то примитивный - определение пинга. Код:
|
|
24.09.2007, 14:28 | #4 |
Старожил
Регистрация: 13.12.2006
Сообщений: 3,859
|
при пинге не удастся, программа будет "думать" до 5-и секунд, пока не получит ответ от удаленного хоста, можно попробовать использовать не Indy для пинга:
Вот известный пример в интернете: type IPINFO = record Ttl: char; Tos:har; IPFlags: char; OptSize: char; Options: ^char; end; объявляем структурку для хранения ICMP пакета: type ICMPECHO = record Source: longint; Status: longint; RTTime: longint; DataSize: Shortint; Reserved: Shortint; pData: ^variant; i_ipinfo: IPINFO; end; Объявляем функции и процедуры, которые мы будем вызывать из ICMP.DLL TIcmpCreateFile = function():integer; {$IFDEF WIN32} stdcall; {$ENDIF} TIcmpCloseHandle = procedure(var handle: integer); {$IFDEF WIN32} stdcall; {$ENDIF} TIcmpSendEcho = function(var handle: integer; endereco: DWORD; buffer: variant; tam: WORD; IP: IPINFO; ICMP: ICMPECHO; tamicmp: DWORD; tempo: DWORD): DWORD; {$IFDEF WIN32} stdcall; {$ENDIF} В TButton в событие Onclick вставляем следующий код: procedure TForm1.Button1Click(Sender: TObject); var wsadt : wsadata; icmp :icmpecho; HNDicmp : integer; hndFile :integer; Host :PHostEnt; Destino :in_addr; Endereco :^DWORD; IP : ipinfo; Retorno :integer; dwRetorno :DWORD; x :integer; IcmpCreateFile : TIcmpCreateFile; IcmpCloseHandle : TIcmpCloseHandle; IcmpSendEcho : TIcmpSendEcho; begin if (edit1.Text = '') then begin Application.MessageBox('Enter a HostName ro a IP Adress', 'Error', MB_OK); exit; end; HNDicmp := LoadLibrary('ICMP.DLL'); if (HNDicmp <> 0) then begin @IcmpCreateFile := GetProcAddress(HNDicmp,'IcmpCreateF ile'); @IcmpCloseHandle := GetProcAddress(HNDicmp,'IcmpCloseHa ndle'); @IcmpSendEcho := GetProcAddress(HNDicmp,'IcmpSendEch o'); if (@IcmpCreateFile=nil) or (@IcmpCloseHandle=nil) or (@IcmpSendEcho=nil) then begin Application.MessageBox('Error getting ICMP Adress’,'Error', MB_OK); FreeLibrary(HNDicmp); end; end; Retorno := WSAStartup($0101,wsadt); if (Retorno <> 0) then begin Application.MessageBox('Canґt Load WinSockets','WSAStartup', MB_OK); WSACleanup(); FreeLibrary(HNDicmp); end; Destino.S_addr := inet_addr(Pchar(Edit1.text)); if (Destino.S_addr = 0) then Host := GetHostbyName(PChar(Edit1.text)) else Host := GetHostbyAddr(@Destino,sizeof(in_ad dr), AF_INET); if (host = nil) then begin Application.MessageBox('Host not found','Error', MB_OK); WSACleanup(); FreeLibrary(HNDicmp); exit; end; memo1.Lines.Add('Pinging ' + Edit1.text); Endereco := @Host.h_addr_list; HNDFile := IcmpCreateFile(); for x:= 0 to 4 do begin Ip.Ttl := char(255); Ip.Tos := char(0); Ip.IPFlags := char(0); Ip.OptSize := char(0); Ip.Options := nil; dwRetorno := IcmpSendEcho( HNDFile, Endereco^, null, 0, Ip, Icmp, sizeof(Icmp), DWORD(5000)); Destino.S_addr := icmp.source; Memo1.Lines.Add('Ping ' + Edit1.text); end; IcmpCLoseHandle(HNDFile); FreeLibrary(HNDicmp); WSACleanup(); end; У данного примера есть один недостаток - программа не воспримет доменное имя, только IP-адресс. Для пользователей NT не используйте функцию IcmpCloseHandle.
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Запуск программы на выполнение из другой программы. | ViNcHeStEr | Паскаль, Turbo Pascal, PascalABC.NET | 6 | 18.06.2008 14:33 |
Две программы | Манжосов Денис :) | Софт | 2 | 26.04.2008 12:29 |
программы | koyot | Фриланс | 1 | 14.03.2008 13:10 |
"Подвисание" программы. | skdon | Работа с сетью в Delphi | 6 | 18.11.2007 00:30 |
Программы | Simply-Art | Свободное общение | 4 | 18.09.2007 22:41 |