【问题标题】:Mailslot blocking forever邮槽永远阻塞
【发布时间】: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 只是一个测试代码,没有任何问题

标签: delphi ipc mailslot


【解决方案1】:

使用线程从邮槽读取。否则,您将始终遇到在 ReadFile 中等待时必须处理 Windows 消息的问题。

话虽如此,对 CreateMailslot 和 ReadFile 的调用看起来与我使用的非常相似(在 XP 及更高版本上),除了我有更大的缓冲区 (65535)。

如果这些都没有帮助,那么问题可能出在其他地方。

当你需要取消对 ReadFile 的调用时,从主线程调用CloseHandle(hand)。当您需要退出线程时,这很有用。这是为邮槽使用线程的另一个原因。

【讨论】:

  • 我会在不同的线程中尝试,对此也很感兴趣。我会和你分享结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
相关资源
最近更新 更多