![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Named Pipes [NT4, Win2k, WinXP]
Nostradamus © (2006-05-06 03:35:00)Помогите, пожалуйста, разобраться с Named pipes.
Создаю pipe на сервере:
hPipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE OR PIPE_NOWAIT, 1, 0, 0, 0, nil);
Открываю pipe на клиенте:
fPipeHandle := CreateFile(PCHAR(fPipeName), GENERIC_READ OR GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
Шлю команды на сервер:
var
S : String;
WriteFile(fPipeHandle, PChar(S)^, Length(S), bytesWrite, nil);
Всё ок...
На клиенте жду от сервера ответа:
const
BytesToRead = 1024;
var
bytesRead : Cardinal;
Buffer: array [0..BytesToRead] of Char;
ReadFile(fPipeHandle, Buffer, BytesToRead, bytesRead, nil);
НО если сервер ничего не отвечает клиенту то клиент виснет :( т.к. ReadFile не возвращает управление проге.
Как этого избежать?
TThread что характерно, тоже не помог.
Eraser (2006-05-06 19:31:00) [1]суть в том, что надо отделить мух от котлет и выполнять отсылку данных в одном потоке, работу с консольным в водом в другом, а главный поток вообще оставить в покое для GUI.
Eraser (2006-05-06 19:29:00) [2]
> Nostradamus (06.05.06 19:24) [13]
дык в том примере так и сделано...
Nostradamus (2006-05-06 19:24:00) [3]
> а задача какая, потому что я не очень понял нужен синхронный
> или асинхронный режим? От этого многое зависит.
Мне всё равно, точне нужен скорее синхронный режим.
Проблема в том, что программа не отвечает пока сервер не пошлёт ответ.
Нужно чтобы не смотря на то, что сервер ничего не послал работал UI.
> + см. http://www.delphimaster.ru/articles/named_pipes/index.
> html
Смотрел уже, но разобраться как решить мою проблему так и не удалось :(
Eraser (2006-05-06 18:45:00) [4]
> Nostradamus (06.05.06 17:07) [11]
а задача какая, потому что я не очень понял нужен синхронный или асинхронный режим? От этого многое зависит.
+ см. http://www.delphimaster.ru/articles/named_pipes/index.html
Nostradamus (2006-05-06 17:07:00) [5]Справку читал долго и нудно.
Я пробовали и с OVERLAPPED и без и с PIPE_NOWAIT всё равно не могу добиться нужного результата.
Очевидно с ReadFile так и не получится, но почему
PeekNamedPipe(fPipeHandle, @Buffer, BytesToRead, @BytesRead, @BytesAvail, @BytesRem);
в буфер ничего не попадает?
Сергей М. (2006-05-06 16:45:00) [6]
> Если сервер ничего не отвечает, то ReadFile не возвращает
> управление, не смотря на OVERLAPPED-режим
.. и это совершенно нормальное явление для OVERLAPPED-режима.
Справку читал ?
Nostradamus (2006-05-06 16:37:00) [7]
> А где анализ результата вызова ConnectNamedPipe ?
>
> И почему экз-р пайпа явно создается тобой для работы в OVERLAPPED-
> режиме, но при этом OVERLAPPED-структура нигде не используется
> - ни в ConnectNamedPipe, ни в ReadFile, ни в WriteFile
> ?
>
Учёл Ваши замечания:
Сервер:
var
hEvent: THANDLE;
OverLap: OVERLAPPED;
hPipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX OR FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 0, 0, 0, nil);
if hPipe = Invalid_Handle_Value then
MessageBox(Handle, 'Unable to create a named pipe', 'Error', MB_OK)
else begin
hEvent := CreateEventW(nil, True, False, nil);
FillChar(Overlap, SizeOf(OVERLAPPED), 0);
Overlap.hEvent := hEvent;
if not ConnectNamedPipe(hPipe, @Overlap) then
MessageBox(Handle, PCHAR(SysErrorMessage(GetLastError)), 'Error', MB_OK);
end;
Клиент:
const
BytesToRead = 1024;
var
hEvent: THANDLE;
OverLap: OVERLAPPED;
bytesRead : Cardinal;
Buffer: array [0..BytesToRead] of Char;
begin
hEvent := CreateEventW(nil, True, False, nil);
FillChar(Overlap, SizeOf(OVERLAPPED), 0);
Overlap.hEvent := hEvent;
if ReadFile(fPipeHandle, Buffer, BytesToRead, bytesRead, @Overlap) then
SetString(Reply, Buffer, BytesRead);
Если сервер ничего не отвечает, то ReadFile не возвращает управление, не смотря на OVERLAPPED-режим :(
Сергей М. (2006-05-06 15:57:00) [8]А где анализ результата вызова ConnectNamedPipe ?
И почему экз-р пайпа явно создается тобой для работы в OVERLAPPED-режиме, но при этом OVERLAPPED-структура нигде не используется - ни в ConnectNamedPipe, ни в ReadFile, ни в WriteFile ?
Сергей М. (2006-05-06 15:55:00) [9]А где анализ результата вызова ConnectNamedPipe ?
Nostradamus (2006-05-06 14:32:00) [10]>Кстати код передачи покажи
Я имел ввиду, что какие-то параметры в функции не правильно передаю, а данные именно так и передаются:
WriteFile(fPipeHandle, S, Length(S), bytesWrite, nil);
>^ -это зачем?
Это я прогнал :), но если это убрать, то всё равно ничего не меняется
>А где ConnectNamedPipe() ?
hPipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX OR FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE OR PIPE_NOWAIT, 1, 0, 0, 0, nil);
if hPipe <> INVALID_HANDLE_VALUE then
ConnectNamedPipe(hPipe, nil)
Сергей М. (2006-05-06 08:09:00) [11]
> Nostradamus (06.05.06 03:35)
А где ConnectNamedPipe() ?
Slym (2006-05-06 06:10:00) [12]WriteFile(fPipeHandle, PChar(S) ^, Length(S), bytesWrite, nil);
^ -это зачем?
Slym (2006-05-06 06:09:00) [13]Nostradamus (06.05.06 5:58) [2]
что я что-то не правильно передаю
Кстати код передачи покажи
Nostradamus (2006-05-06 05:58:00) [14]
> 1. ReadFile(fPipeHandle, Buffer, BytesToRead, bytesRead,
> nil); не передавай nil
Я с overlapped пробовал - тоже, что-то не сложилось, не подскажешь конкретнее?
Я делал так:
На сервере:
hPipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX OR FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE OR PIPE_NOWAIT, 1, 0, 0, 0, nil);
На клиенте:
hEvent := CreateEventW(nil, True, False, nil);
FillChar(Overlap, SizeOf(OVERLAPPED), 0);
Overlap.hEvent := hEvent;
ReadFile(fPipeHandle, Buffer, BytesToRead, bytesRead, @Overlap);
> 2. PeekNamedPipe
Не виснет, но и в буфере почему-то ничего нет даже когда сервер таки отсылает ответ :(
FillChar(Buffer, SizeOf(Buffer), 0);
PeekNamedPipe(fPipeHandle, @Buffer, BytesToRead, @BytesRead, @BytesAvail, @BytesRem);
У меня такое чувство, что я что-то не правильно передаю, но что - не пойму.
Slym (2006-05-06 04:34:00) [15]1. ReadFile(fPipeHandle, Buffer, BytesToRead, bytesRead, nil); не передавай nil
2. PeekNamedPipe