Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Именованный пайп и CreateFile

5.3K
12 января 2008 года
Somebody
185 / / 24.12.2006
Ждёт ли CreateFile на стороне клиента, если пайп создан с атрибутом PIPE_WAIT? Ну я попробовал - результаты неоднозначные. Почему?
Сервер:
Код:
{$APPTYPE CONSOLE}
uses Windows;
var hPipe:THandle;
    si:STARTUPINFO;
    pi:PROCESS_INFORMATION;
begin
hPipe:=CreateNamedPipe('\\.\pipe\SomeName',PIPE_ACCESS_DUPLEX,PIPE_WAIT,1,$100,$100,0,nil);
FillChar(si,SizeOf(si),0); si.cb:=SizeOf(si);
CreateProcess(nil,'Client.exe 1',nil,nil,false,0,nil,nil,si,pi);
CloseHandle(pi.hThread);
Sleep(2000); //This Sleep does nothing bad
ConnectNamedPipe(hPipe,nil);
WaitForSingleObjectEx(pi.hProcess,INFINITE,false);
DisconnectNamedPipe(hPipe);
CloseHandle(pi.hProcess);
CreateProcess(nil,'Client.exe 2',nil,nil,false,0,nil,nil,si,pi);
CloseHandle(pi.hThread);
Sleep(2000); //But not this one
ConnectNamedPipe(hPipe,nil);
WaitForSingleObjectEx(pi.hProcess,INFINITE,false);
DisconnectNamedPipe(hPipe);
CloseHandle(pi.hProcess);
CloseHandle(hPipe);
end.

Клиент:
Код:
{$APPTYPE CONSOLE}
uses Windows;
var hPipe:THandle;
    Buf:array [0..99] of Char;
begin
hPipe:=CreateFile('\\.\pipe\SomeName',GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,GetLastError(),0,@Buf,100,nil);
MessageBox(0,@Buf,nil,MB_ICONEXCLAMATION);
if hPipe=INVALID_HANDLE_VALUE then Write(':-(( ',ParamStr(1));
CloseHandle(hPipe);
end.

Из-за первого Sleep'а ничего плохого, можно ставить любой период (CreateFile ждёт), но если период второго Sleep'а достаточен, чтобы клиентский CreateFile был вызван раньше серверного ConnectNamedPipe, то ничего хорошего: hPipe=INVALID_HANDLE_VALUE, FormatMessage от GetLastError: "Все копии канала заняты".
5.3K
21 февраля 2008 года
Somebody
185 / / 24.12.2006
CreateFile ждёт вроде бы, но проблема не решилась с помощью WaitNamedPipe, да и выяснилось, что проблема-то на стороне сервера. А теперь причины её возникновения.
Cервер может принять клиента при наличии свободных экземпляров пайпа в любое время после первого вызова ConnectNamedPipe. Выходит, что при вызове второго ConnectNamedPipe'а, если есть Sleep, клиент уже подсоединился. Но GetLastError немного разъясняет ситуацию. Надо только проверить, если он даёт ERROR_PIPE_CONNECTED, то не нужно ждать соединения – оно уже есть к моменту вызова ConnectNamedPipe'а.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог