2

我已经阅读了我能找到的关于邮槽的所有内容,但仍然存在写入已由另一台计算机上的邮槽服务器打开以供读取的邮槽的问题。

我对同一台计算机上的邮槽没有问题。例如,如果我尝试像这样写入本地计算机上的邮槽:

var
  sMsg: string;
  iBytes: DWORD;
begin
  SlotName := '\\.\mailslot\testslot';
  Handle := CreateFile(PChar(SlotName), GENERIC_WRITE, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Result := WriteFile(Handle, sMsg[1], Length(sMsg), iBytes, nil);
end;

CreateFile如果邮槽服务器程序没有创建邮槽,将失败并显示文件不存在错误代码。

但是,如果我将这样\\MYSERVER\mailslot\testslot的内容作为邮槽名称传递,它总是返回一个有效的文件句柄。即使计算机名无效,它仍然返回一个文件句柄,然后WriteFile也成功。

如果计算机名称不正确或该计算机上的邮槽服务器没有创建邮槽,我希望CreateFile失败,但这似乎不是这种情况,只有在写入本地计算机上的邮槽时才会出现这种情况.

有人可以启发我吗?

4

1 回答 1

3

CreateFile()文档指出:

邮槽

如果 CreateFile 打开邮槽的客户端,如果邮槽客户端在邮槽服务器使用 CreateMailSlot 函数创建本地邮槽之前尝试打开本地邮槽,则该函数返回 INVALID_HANDLE_VALUE。

这意味着CreateFile()无法验证远程邮槽的存在,只能验证本地邮槽。这与您所看到的行为一致。Windows 可以轻松验证本地邮槽是否存在,但无法验证远程邮槽是否存在。当您考虑到邮槽是使用数据报(又名 UDP)实现时,这是有道理的。UDP 无法知道远程目的地是否存在。它所能做的就是在网络上放一个数据包,并希望它到达目的地。这在 Mailslot文档中有所说明:

一个重要的考虑因素是邮槽使用数据报广播消息。数据报是网络沿线路发送的一小段信息。与广播或电视广播一样,数据报不提供接收确认;无法保证已收到数据报。就像山脉、大型建筑物或干扰信号可能会导致无线电或电视信号丢失一样,有些事情会阻止数据报到达特定目的地。

这就是当远程邮槽不存在时不会失败的CreateFile()原因。WriteFile()他们根本不知道其中一种方式。

于 2014-12-10T18:14:29.263 回答