【发布时间】:2015-05-27 20:13:48
【问题描述】:
我决定为 IPC 使用邮槽。在 Windows 8 上一切正常。但是在 Windows Xp 上,我收到了很好的第一条消息,但是对 ReadFile 的调用被卡住了。
这是我的测试代码:
procedure TForm1.Button1Click(Sender: TObject);
var
hand : THandle;
buf : array [0..255] of AnsiChar;
btsRead : DWORD;
begin
hand := CreateMailslot('\\.\mailslot\somemailslot', 255, DWORD(-1), nil);
if hand <> INVALID_HANDLE_VALUE then
begin
while True do
begin
ReadFile(hand, buf, 255, btsRead, nil); // call gets stuck after first message
ShowMessage(buf);
Application.ProcessMessages;
end;
end;
在 Windows 8 上,我继续从客户端应用程序接收消息,但在 Windows xp 上,对 ReadFile 的调用会永远阻塞等待消息。我尝试重新打开客户端应用程序但没有成功。
我做错了什么?
【问题讨论】:
-
你的第三个参数设置为-1,表示
MAILSLOT_WAIT_FOREVER。如果没有消息,它将阻塞。你确定要发送一个吗?您重新启动客户端,但服务器在做什么? (顺便说一句,循环和调用Application.ProcessMessages是一种可怕的设计——如果这不是一个测试应用程序,你能以不同的方式构造它吗?) -
在尝试阅读第二条消息之前,您是否检查过
GetMailslotInfo的内容? -
看看 MSDN 的例子:Reading from a Mailslot。它使用
GetMailslotInfo()来确定是否有消息在等待,然后使用ReadFile()和重叠的I/O 来读取它们。您也可以将CreateMailslot()的lReadTimeout参数设置为MAILSLOT_WAIT_FOREVER(-1) 以外的任何值,这样如果在超时期限内没有消息到达,阻塞ReadFile()最终将超时并退出。 -
另外,服务器是如何发送消息的?它们的大小总是 255 字节吗?
-
客户端正在发送 255 字节的消息,但从未收到。为什么我应该使用不同的方法,当它工作得很好并且在 msdn 中有记录时。另外@DavidM 只是一个测试代码,没有任何问题