Форум: "Сети";
Текущий архив: 2002.10.07;
Скачать: [xml.tar.bz2];
ВнизПереход c WSAAsyncSelect на WSAEventSelect проблемы. Найти похожие ветки
← →
MaxIII (2002-08-07 19:32) [0]Вот решил избавиться от форм (написать консольное приложение) в связи с чем уйти от WSAAsyncSelect-а.
AsyncSelect переправлял сообщение на указанный мной обработчик:
const
MyMsg = WM_USER + 167;
...
Form1 = class(TForm)
public
mywindow : hWnd;
procedure Myreader(var Msg : TMessage); message MyMsg
...
procedure TForm1.FormCreate(Sender: TObject);
...
mywindow := form1.handle;
WSAAsyncSelect(s, mywindow, MyMsg, FD_READ);
procedure Tform1.Myreader(var Msg : TMessage);
var ...
begin
// Все замечательно сюда приходит
Но как только перехожу на
WSAEventSelect(s, mywindow, FD_READ);
сразу вопрос - как перехватывать то, что пришло?
Не так ведь
procedure Myreader(var Msg : TMessage); message Что и как?;
← →
Digitman (2002-08-08 08:34) [1]Ты вообще-то читал описание к WSAEventSelect ? Эта ф-ция никакого отношения к оконным сообщениям не имеет.
И почему в консольном приложении нельзя использовать WSAAsyncSelect - тоже неаонятно. Ведь ничто не мешает тебе создавать свои оконные объекты в таком приложении ...
← →
MaxIII (2002-08-08 10:27) [2]Ты вообще-то читал описание к WSAEventSelect ? Эта ф-ция никакого отношения к оконным сообщениям не имеет.
А как перехватывать сообщения без использования окон?
И почему в консольном приложении нельзя использовать WSAAsyncSelect - тоже неаонятно. Ведь ничто не мешает тебе создавать свои оконные объекты в таком приложении ...
Создвавать окна в консольном приложении ради перехвата сообщений это, imho, не совсем правильно.
← →
Digitman (2002-08-08 10:46) [3]
> А как перехватывать сообщения без использования окон?
А о каких сообщениях идет речь в ф-ции WSAEventSelect ? Ни о каких не идет. Из другой "оперы" это. Поэтому и спрашиваю, читал ли, видишь ли радикальные отличия в работе механизмов извещения о транспортных событиях : с помощью оконных сообщений (WSAAsyncSelect) и с помощью объектов синхронизации (WSAEventSelect)
> Создвавать окна в консольном приложении ради перехвата сообщений
> это, imho, не совсем правильно.
Это почему же ? Если некий объект может генерировать извещения не иначе как только с помощью механизма оконных сообщений, что ж теперь - его нельзя использовать в консольном процессе ?
← →
MaxIII (2002-08-08 11:16) [4]Я не программист (админ, который иногда балуется делфи), поэтому, не обращайте на ошибки. Задача моя: написать прогу которая слушает UDP порт, парсит данные и складывает получаемые данные в логи.
Создал оконное приложение с помощью WSAAsyncEvent все замечательно работает. Теперь у меня остались 2 проблемы:
1) Правильнее сделать таки в виде NT service
2) Надо както засунуть все в threads (так как получаю данные от разных устройств и возможно они поступят параллельно).
Далее мне кажется использование WinSock2 средств WSAEventSelect / WSAEnumNetworkEvents / WSAWaitForMultipleEvents более правильным . Помогите, пожалуйста, организовать сам процесс
Слушать порт, при FD_READ переслать на процедуру обработки + прикрутить threads. Пиво обещаю (бандероль вышлю)!!!!!
← →
Digitman (2002-08-08 13:10) [5]Если "балуешься" - вряд ли чем-то помогу. Если взялся серьезно - другое дело.
Давай так лучше - ты задаешь вопрос за вопросом о непонятном тебе во всей этой цепочке, а я отвечаю. Ok ?
P.S. Пиво можешь оставить себе) ... я пью исключительно "Жигулевское", произведенное только на родном для пива "Жигулевское" - нашем фон-ваканоновском пивзаводе...
← →
Alex Demchenko (2002-08-08 13:29) [6]> MaxIII
Треды необязательны если используешь blocking-sockets, на разные соединения идут разные сокеты, в один и тот же сокет нельзя посылать одновременно 2-а потока данных.
← →
Digitman (2002-08-08 13:54) [7]>Alex Demchenko
Если ты о мультипоточной синхронизации транспортных ф-ций гнезда, то, как помнится, как минимум в WS2 они изначально thread-safe ...
несмотря на дополнительные меры по синхронизации, принятые Борландом в scktcomp.pas (понимаю - почему : Борланд базирует гнездовые компоненты на WS v1.1), можно и без них обойтись в принципе, опираясь на возможности последних версий WS
← →
MaxIII (2002-08-08 14:24) [8]Digitman Под словом балуюсь я имел в виду то, что я программирую на Delphi от случая к случаю (я сисадмин).
А серьезно мне надо делать следующее: читать на порту UDP данные и отпарсив их складывать в логи на WinNT (поэтому и хочу сделать как сервис). Все замечательно работало когда я сделал тестовую [b]форму[/b] и через WSAAsyncSelect(s, mywindow, MyMsg, FD_READ) переправлял все события на заранее определенный обработчик событий (FD_READ = WM_USE + const). Но меня начмнали грызть сомнения по поводу правильности всего этого и я решил перейти на WinSock2 и цепочку WSAEventSelect -> WSAEnumNetworkEvents -> WSAWaitForMultipleEvents. И как добиться чтобы поймать message и начать его обработку не знаю :(((( Приведите простой пример с применением данной цепочки, пожалуйста.
P.S. А теперь передо мной еще задача. Если до этого на UDP сыпало данное одно устройство, в дальнейшем их предполагается 15 и Alex Demchenko , пожалуйста, объясни поподробней что и как (или дай ссылки.
Спасибо всем огромное.
← →
Digitman (2002-08-08 14:53) [9]Вот тебе код :
procedure TServerTransportThread.ClientExecute;
var
SocketEvent: THandle;
NetworkEvents: TWSANetworkEvents;
NewOptVal: Integer;
FDataBlock: IDataBlock;
begin
FITransport:= CreateTransport;
try
SocketEvent := FITransport.GetWaitEvent;
NewOptVal := Integer(True);
CheckWSAResult(SetSockOpt(FSocketHandle, SOL_SOCKET, SO_OOBINLINE, @NewOptVal, SizeOf(NewOptVal)), "SetSockOpt");
CheckWSAResult(WSAEventSelect(FSocketHandle, SocketEvent, FD_READ or FD_CLOSE or FD_OOB), "WSAEventSelect");
while not Terminated and FITransport.Connected do begin
case MsgWaitForMultipleObjects(1, SocketEvent, False, INFINITE, QS_POSTMESSAGE) of
WAIT_OBJECT_0:
begin
CheckWSAResult(WSAEnumNetworkEvents(FSocketHandle, SocketEvent, @NetworkEvents), "WSAEnumNetworkEvents");
with NetworkEvents do
if Boolean(lNetworkEvents and FD_READ) then
case iErrorCode[FD_READ_BIT] of
NO_ERROR:
begin
FIDataBlock:= FITransport.Receive(False, 0);
end;
else
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketRead, iErrorCode[FD_READ_BIT], SysErrorMessage(iErrorCode[FD_READ_BIT])]);
end
else if Boolean(lNetworkEvents and FD_CLOSE) then
case iErrorCode[FD_CLOSE_BIT] of
NO_ERROR: break;
WSAECONNRESET: break;
WSAECONNABORTED: break;
else
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketClose, iErrorCode[FD_CLOSE_BIT], SysErrorMessage(iErrorCode[FD_CLOSE_BIT])]);
end
else if Boolean(lNetworkEvents and FD_OOB) then
case iErrorCode[FD_OOB_BIT] of
NO_ERROR:; // нет в тек.реализации
else
raise ESocketError.CreateResFmt(@sSocketIOError, [sSocketClose, iErrorCode[FD_OOB_BIT], SysErrorMessage(iErrorCode[FD_OOB_BIT])]);
end;
end;
WAIT_OBJECT_0 + 1:
while PeekMessage(FMsg, 0, 0, 0, PM_REMOVE) and not Terminated do
Dispatch(FMsg.Message);
WAIT_TIMEOUT:;
end;
end;
finally
FITransport:= nil;
end;
end;
сомневаюсь, что вопросов не возникнет - еще больше будет)
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2002.10.07;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.009 c