![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Про pipe'ы. [D7, WinXP]
h8394E © (2006-04-05 04:14:00)Вот, в статье на вашем сайте, по адрессу http://www.delphimaster.ru/articles/named_pipes/index.htmlприведён и код, и исходники. Одна проблема... Я в Windows API не очень смыслю, но как я понял, там же именно на них окна и создавались. А я в своём приложении формы делаю... Помогите пожалуйста, переведите те исходники для сервера и клиента... У сервера мне только чнение pipe'ы надо, а клиент запускается-то на несколько милисекунд.
Eraser (2006-04-08 18:50:00) [1]
> h8394E (08.04.06 16:33) [11]
TMyThread.Synchronize(ShowData);
всё таки, прежде чем писать многопоточные приложения, неплохо бы книжку почитать по программированию какую-нибудь :)
h8394E (2006-04-08 16:33:00) [2]
> см. метод TThread.Synchronize()
Странно, но даже так при вызове процедуры, где form1.memo1.lines.add(EPData.name); - выходит ошибка. Делал так:
TMyThread.Synchronize(ShowData);
...
TMyThread. ShowData;
begin
form1.memo1.lines.add(EPData.name);
end;
Сергей М. (2006-04-07 08:53:00) [3]
> Вот клиент
В целом - ничего криминального ..
> Запускаю процедуру, что выше первый раз - ничего
Почему не анализируешь результата вызова WriteFile() ?
Почему hPipe не закрываешь после завершения обмена с сервером ?
> Проект Server.exe вызвал исключение языка EAccessViolation
> по адресу...
Собери проект сервера с опциями отладки. Запусти под отладчиком.
Сразу же в меню Search -> Find Error .. введи этот самый адрес - отладчик с достаточной долей вероятности покажет тебе строчку в исх.тексте серверного приложения, которая вызвала исключение.
И вообще - отладчик на то и дан, чтобы пользоваться им для поиска ошибок и отладки.
> как его асинхронным сделать
см. в справке все касающееся overlapped-режима для ф-ций, работающих с пайпами.
> как мне тогда пришедшие данные показать?
см. метод TThread.Synchronize()
> Там чё-то для Delphi 2 в Win95
Тот код достаточно легко адаптируется к D7.
У тебя WinXP указан, так что тебя ограничения пайпов для Win95 тебя не касаются. Да и не будет пайп-сервер работать под Win9x вообще.
> В нём асинхронное соединение вообще сделать нельзя
Там как раз синхронный транспорт использован.
h8394E (2006-04-07 01:04:00) [4]Сергей М, Вот клиент(точнее процедура только отправки в pipe)
procedure SendToServer(Data: TEnterPipe);
const
MAX_WRITE = SizeOf(Data);
var
hPipe: THandle;
bytesWritten: DWORD;
LastError: DWORD;
begin
hPipe := CreateFile('\\.\PIPE\TMApipe',
GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hPipe = INVALID_HANDLE_VALUE then
begin
form1.Memo1.Lines.Add('No pipe found');
Exit;
end;
WriteFile(hPipe, Data, MAX_WRITE, bytesWritten, nil)
end;
> Все правильно - вызов-то блокирующий ..
А как его асинхронным сделать (я так понимаю ты это имел ввидую Если нет, то как сделать не блокирующим)?
> Какого "второго" ? Первое еще не произошло, сам же говоришь
> - "сервер виснит" ..
Ну, так я сервак запускаю - он повешен. Запускаю процедуру, что выше первый раз - ничего. А при втором даёт ошибку "Проект Server.exe вызвал исключение языка EAccessViolation по адресу..." И так далее...
Ошибка из-за
> Обращение к визуальным VCL-контролам в дополнительном потоке
> процесса VCL-приложения не допустимо.
А как мне тогда пришедшие данные показать?
> Еще одна реализации NP-транспорта
Там чё-то для Delphi 2 в Win95. В нём асинхронное соединение вообще сделать нельзя, насколько я знаю.
Сергей М. (2006-04-06 10:04:00) [5]Еще одна реализации NP-транспорта в Делфи-компонентах + демо-проект:
http://ourworld.compuserve.com/homepages/mikes/NPipes02.zip
Сергей М. (2006-04-06 08:31:00) [6]
> ConnectNamedPipe(hPipe, nil); //вот здесь виснит
Все правильно - вызов-то блокирующий ..
Так и будет висеть, пока очередь клиентских запросов на подключение пуста.
Как только будет обнаружен очередной запрос, ф-ция акцептирует его и тут же вернет управление.
> после пторого подключения клиета
Какого "второго" ? Первое еще не произошло, сам же говоришь - "сервер виснит" ..
А где, кстати, код клиента ? Приводи уж и его тоже до кучи ...
> сервер ошибку выдаёт
Какую конкретно ?
p.s.
Обращение к визуальным VCL-контролам в дополнительном потоке процесса VCL-приложения не допустимо.
h8394E (2006-04-06 03:24:00) [7]Так, вот, кое-как разобрался, написал так:
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type TEnterPipe = packed record
Name:string;
IP:string;
bEvent:byte;
end;
type
TNamedPipeThread = class(TThread)
private
EPdata:TEnterPipe;
Terminated: boolean;
protected
procedure Execute; override;
public
procedure ShowData;
procedure AddToLog(s:string);
procedure TurnOff;
constructor Create(CreateSuspended: Boolean); reintroduce; overload;
end;
var
Form1: TForm1;
TrPipe: TNamedPipeThread;
implementation
{$R *.dfm}
{ TNamedPipeThread }
procedure TNamedPipeThread.AddToLog(s:string);
begin
form1.Memo1.Lines.Add(s);
end;
constructor TNamedPipeThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
if not CreateSuspended then Execute;
end;
procedure TNamedPipeThread.Execute;
const
MAX_PIPE_INSTANCES = 10;
OUT_BUF_SIZE = SizeOf(EPdata);
MAX_READ = SizeOf(EPdata);
TIME_OUT = 100;
var
hPipe: THandle;
bytesRead: DWORD;
begin
terminated:=false;
try
hPipe := CreateNamedPipe('\\.\PIPE\TMApipe',
PIPE_ACCESS_INBOUND,
PIPE_WAIT or
PIPE_READMODE_MESSAGE or
PIPE_TYPE_MESSAGE,
MAX_PIPE_INSTANCES,
OUT_BUF_SIZE,
OUT_BUF_SIZE,
TIME_OUT,
nil);
if hPipe = INVALID_HANDLE_VALUE then
begin
AddToLog('Error - CreateNamedPipe');
Exit;
end;
while true do //Даже если безконечный цыкл убрать, то
begin
try
ConnectNamedPipe(hPipe, nil); //вот здесь виснит
if ReadFile(hPipe, EPdata, MAX_READ, bytesRead, nil) then
begin
ShowData;
end;
finally
DisconnectNamedPipe(hPipe);
end;
end;
finally
end;
end;
procedure TNamedPipeThread.ShowData;
begin
form1.Memo2.Lines.Add('New user: '+EPData.Name);
case epdata.bEvent of
1: form1.Memo2.Lines.Add('Have registrated.');
2: form1.Memo2.Lines.Add('Have entered.');
3: form1.Memo2.Lines.Add('Trying to registrate.');
end;
form1.Memo2.Lines.Add('His IP is: '+EPData.IP);
end;
procedure TNamedPipeThread.TurnOff;
begin
Terminated:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TrPipe:=TNamedPipeThread.Create(false);
end;
end.
Так вот, почему-то программа виснит. А после пторого подключения клиета сервер ошибку выдаёт, и перестаёт работать.
Вопрос: правилен и код?
Игорь Шевченко (2006-04-05 11:08:00) [8]Формы делать - тоже хорошее занятие
Fay (2006-04-05 10:34:00) [9]Полный текст примера сервера и клиента, использующих именованный канал для коммуникации можно найти
в приложениик статье.
balepa (2006-04-05 09:11:00) [10]
> Сергей М. © (05.04.06 08:33) [2]
Автор наверное имел ввиду на WinApi, хотя я в статье этого не увидел (мож пплохо смотрел)
Сергей М. (2006-04-05 08:33:00) [11]
> там же именно на них окна и создавались
Окна не имеют никакого отношения к пайпам.
balepa (2006-04-05 06:38:00) [12]Там же блин коментариев в каждой строчке по 2 (по 3 по 4 и т.д.) + книжек много разных есть + интернет.
А в WinApi надо смыслить начинать. И встречный вопрос что понимать под -
"Помогите пожалуйста, переведите те исходники для сервера и клиента" тебе че на китайский перевести ?