我用管道在两个进程之间通信,但客户端总发生异常说拒绝访问指定管道.这是不是因为NT的安全机制引起的?
服务器端.
procedure TForm1.Button1Click(Sender: TObject);
const
pipename:string='\\.\pipe\zwpipe';
var
SPipeHandle:THandle;
Se:TSecurityAttributes;
WriteBuffer:DWORD;
Buffer:pchar;
begin
Se.nLength:=Sizeof(TSecurityAttributes);
Se.lpSecurityDescriptor:=nil;
Se.bInheritHandle:=True;
SPipeHandle:=CreateNamedPipe(pchar(pipename),PIPE_ACCESS_OUTBOUND OR FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_BYTE or PIPE_WAIT,2,512,0,1000,@Se);
if SPipeHandle=-1 then
raise Exception.Create('Create pipe Failed');
try
if not ConnectNamedPipe(SPipeHandle,nil) then begin
CloseHandle(SPipeHandle);
Raise Exception.Create(IntToStr(GetLastError)+'fail con');end;
Buffer:=StrAlloc(512);
Buffer:=Pchar(Memo1.Text);
WriteFile(SPipeHandle,Buffer,512,WriteBuffer,nil);
finally
DisConnectNamedPipe(SPipeHandle);
CloseHandle(SPipeHandle);
end;
end;客户端.
procedure TForm1.Button1Click(Sender: TObject);
const
PipeName:string='\\ZHOUWEI\pipe\zwpipe';
var
Buffer:pchar;
ReadSize:DWORD;
begin
if not WaitNamedPipe(pchar(PipeName),NMPWAIT_WAIT_FOREVER) then
raise Exception.Create('failed wait');
Buffer:=StrAlloc(512);
if not CallnamedPipe(Pchar(PipeName),nil,0,Buffer,512,ReadSize,NMPWAIT_NOWAIT) then
Raise Exception.Create(IntToStr(GetLastError)+'faid call');
Memo1.Text:=StrPas(Buffer);
end;
服务器端.
procedure TForm1.Button1Click(Sender: TObject);
const
pipename:string='\\.\pipe\zwpipe';
var
SPipeHandle:THandle;
Se:TSecurityAttributes;
WriteBuffer:DWORD;
Buffer:pchar;
begin
Se.nLength:=Sizeof(TSecurityAttributes);
Se.lpSecurityDescriptor:=nil;
Se.bInheritHandle:=True;
SPipeHandle:=CreateNamedPipe(pchar(pipename),PIPE_ACCESS_OUTBOUND OR FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_BYTE or PIPE_WAIT,2,512,0,1000,@Se);
if SPipeHandle=-1 then
raise Exception.Create('Create pipe Failed');
try
if not ConnectNamedPipe(SPipeHandle,nil) then begin
CloseHandle(SPipeHandle);
Raise Exception.Create(IntToStr(GetLastError)+'fail con');end;
Buffer:=StrAlloc(512);
Buffer:=Pchar(Memo1.Text);
WriteFile(SPipeHandle,Buffer,512,WriteBuffer,nil);
finally
DisConnectNamedPipe(SPipeHandle);
CloseHandle(SPipeHandle);
end;
end;客户端.
procedure TForm1.Button1Click(Sender: TObject);
const
PipeName:string='\\ZHOUWEI\pipe\zwpipe';
var
Buffer:pchar;
ReadSize:DWORD;
begin
if not WaitNamedPipe(pchar(PipeName),NMPWAIT_WAIT_FOREVER) then
raise Exception.Create('failed wait');
Buffer:=StrAlloc(512);
if not CallnamedPipe(Pchar(PipeName),nil,0,Buffer,512,ReadSize,NMPWAIT_NOWAIT) then
Raise Exception.Create(IntToStr(GetLastError)+'faid call');
Memo1.Text:=StrPas(Buffer);
end;
解决方案 »
- TActionMenubar的用法
- delphi serversocket 的socket.nindex 是什么意思?
- Delphi数据库数值判断问题!
- 为何 Socket 发送流后,接收端接收的大小与发送的大小不一致(接收的数据总是大于发送的数据)?
- Delphi中的nil转换为数据库中的NULL的随想
- 将一个*.wav加入EXE文件可以了,但是将一个*.mpeg的文件做成一个exe文件应该怎样做啊?
- delphi7中tcpclient如何读出tcpserver发来的数据
- 怎么才能获得ListBox中当前选中项的值
- 谁有Delphi 7写的FTP服务器能给我一份吗?
- 写文件问题! 急!
- 三喜合一,散分!
- 数据模块(DM)一般是生成同一个实例,现在我想生成多个不同的实例,怎么办?
高手们,没有人知道原因吗?
用overlapped结构。
我对管道一点都不熟悉.
overlapped结构是什么?有什么用?
http://www.codeguru.com/network/p2p_namedpipes.shtml
现成下载使用了,
http://www.torry.net/vcl/system/appscommunications/pipe.zip
////server:const
pipename:string='\\.\pipe\zwpipe';
var
SPipeHandle:THandle;
Se:TSecurityAttributes;
WriteBuffer:DWORD;
Buffer:pchar;
begin
Se.nLength:=Sizeof(TSecurityAttributes);
Se.lpSecurityDescriptor:=nil;
Se.bInheritHandle:=True;
SPipeHandle:=CreateNamedPipe(pchar(pipename),PIPE_ACCESS_DUPLEX OR FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_BYTE or PIPE_WAIT,2,512,512,1000,@Se);
if SPipeHandle=-1 then
raise Exception.Create('Create pipe Failed');
try
if not ConnectNamedPipe(SPipeHandle,nil) then begin
CloseHandle(SPipeHandle);
Raise Exception.Create(IntToStr(GetLastError)+'fail con');end;
Buffer:=StrAlloc(512);
Buffer:=Pchar(Memo1.Text);
WriteFile(SPipeHandle,Buffer[0],512,WriteBuffer,nil);
finally
DisConnectNamedPipe(SPipeHandle);
CloseHandle(SPipeHandle);
end;
end;////client:
const
PipeName:string='\\.\pipe\zwpipe';
var
Buffer:array[0..511] of char;
ReadSize:DWORD;
hh:Thandle;
begin
if not WaitNamedPipe(pchar(PipeName),NMPWAIT_USE_DEFAULT_WAIT) then
raise Exception.Create('failed wait');
hh:=CreateFile(pchar(pipename), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or
FILE_SHARE_WRITE,NiL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE or FILE_FLAG_WRITE_THROUGH,0);
if hh=INVALID_HANDLE_VALUE then
showmessage('error createfile')
else
begin
readsize:=0;
fillchar(buffer,512,0);
readfile(hh,buffer,512,readsize,nil);
if readsize >0 then
Memo1.Text:=Buffer;
end;
end;
还是不行,虽然管道连上了,可又提示内存地址出错.
Access violation at address 0040443F in module "client.exe'.Read of address 7A7A7A7A.
我用的WIN2000+SP4+D6.
请再帮忙看看,感激感激.
应该用readfile(hh,buffer,512,readsize,nil);若buffer 定义为pchar;
getmem(buffer,512);
就应为readfile(hh,buffer^,512,readsize,nil);我估计你就错在此
我的程序可是全部调试执行通过
谢谢.问题解决了.我已经结了一贴.马上就结这一贴.
还有些问题想问问.
为什么一定要用CHAR数组?我PCHAR也分配了空间的,为什么会出错?
CREATENAMED()中为什么要用PIPE_ACCESS_DUPLEX 而不用PIPE_ACCESS_OUTBOUND,还有
FILE_SHARE_READ or FILE_SHARE_WRITE,NiL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE or FILE_FLAG_WRITE_THROUGH这几个参数值代表什么意思?客户端的管道名中不是要加上计算机名吗?
在这里先谢过了.
BUFFER[0]而直接用BUFFER?是不是把字串装入了BUFFER后在客户端连结上之前不能释放分配的BUFFER的内存空间?
getmem(buffer,512);
就应为readfile(hh,buffer^,512,readsize,nil);
或readfile(hh,buffer[0],512,readsize,nil);
buffer^和buffer有天壤之别
readfile定义为
function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
buffer定义为引用,而非指针
WriteFile(SPipeHandle,Buffer[0],512,WriteBuffer,nil)也是一样
用PIPE_ACCESS_OUTBOUND应该也可以,客户端的管道名中不须加上计算机名
那几个参数,我也是直接从windows sdk hlp copy过来,自己看一下,我最讨厌打字
1.不能用PIPE_ACCESS_OUTBOUND,只能用PIPE_ACCESS_DUPLEX,我就是这里疑惑.明明只是单向从服务器流到客户端,为什么一定得PIPE_ACCESS_DUPLEX?
2.在CLIENT中用CALLNAMEDPIPE()不管怎样也连不上管道,难道一定得用CREATEFILE()吗?请帮忙调试一下.
3.如果S和C不在同一台计算机上,C中的管道名要不要加上S的名称?
最后一个很菜的问题.....Windows SDK hlp怎么查,如果是查阅MSDN,请给出详细地址,
因为我从未在MSDN上找到这方面的资料.哈哈.
CREATEFILE是M$推荐,我想CALLNAMEDPIPE()可能是过时的用法我一般不用namepipe进行通讯,上次我只是一时性起,才帮你一试