服务器使用重叠的命名pipe道:如何使用ReadFile()与GetOverlappedResult()?

我写了一个服务器和客户端使用重叠的命名pipe道。 我的问题主要是与Readfile()和GetOverlappedResult()。

请注意,这个程序是一个testing代码。 它将稍后集成在一个框架中(我将linux代码移植到使用AF_UNIX地址族进行套接字连接的unix)

我描述服务器部分。 我有2个线程:

1)主线程打开重叠的命名pipe道,然后循环WaitForMultipleObjects()。 WaitForMultipleObjects()等待3个事件:第一个等待客户端连接。 第二个让我彻底退出程序。 在ReadFile()中挂起操作时,第三个信号被发送。

2)第二个线程在客户端连接时启动。 它在ReadFile()上循环。

这里是服务器代码:

http://pastebin.com/5rka7dK7

我主要使用MSDN文档(命名pipe道服务器使用重叠I / O,命名pipe道客户端),SDK和其他文档在互联网上,编写代码。 在[1]中查看客户端代码。 客户端代码需要一些爱,但现在,我专注于使服务器完美工作。

在服务器代码中有4个函数(我忘记显示错误消息的函数):

a)svr_new:创build重叠的命名pipe道和3个事件,并调用ConnectNamedPipe()

b)svr_del释放所有的资源

c)_read_data_cb:调用ReadFile()的线程

d)在WaitForMultipleObjects()上循环的main()函数(主线程)

我的目标是在客户端断开连接(ReadFile()失败,GetLastError()返回ERROR_BROKEN_PIPE)以及数据来自客户端时检测_read_data_cb()。

我不明白的是:

  • 我应该调用GetOverlappedResult()吗?
  • 如果是,在哪里? 当ReadFile()失败,GetLastError()返回ERROR_IO_PENDING(粘贴的第50行)? 当WaitForMultipleObjects()返回(粘贴的第303行,我在那里注释了代码)? 别的地方 ?
  • 当WaitForMultipleObjects()返回(粘贴的第302行)时,我执行ReadFile()事件的ResetEvent。 这是叫它的正确的地方吗?

在我粘贴的代码中,如果客户端发送这24个字节(ReadFile()缓冲区的大小是5字节,那么结果如下:我打算设置该值来testing如果客户端发送的数据大于ReadFile ) 缓冲)

消息:“salut,c'est le客户端!”

输出:

WaitForMultipleObjects:2 * ReadFile:5 WaitForMultipleObjects:2 * ReadFile:5 WaitForMultipleObjects:2 * ReadFile:5 WaitForMultipleObjects:2 * ReadFile:5 WaitForMultipleObjects: 2 * ReadFile:4

注意:WaitForMultipleObjects()可以被称为小于,它似乎是随机的。

因此,在我的代码中,我没有调用getOverlappedResult(),ReadFile()成功(il读取5 * 4 + 4 = 24字节),但是我不知道读取操作何时完成。

注意:当ReadFile()在ERROR_IO_PENDING失败时添加一个printf(),printf()被无限期地调用。

另外,客户端发送2条消息。 一个是上面的,另一个是三秒钟之后。 第二个消息是永远不会读取和ReadFile()失败,错误ERROR_SUCCESS …(所以更确切地说,ReadFile()返回FALSE和GetLastError()返回ERROR_SUCCESS)

所以,我完全失去了。 我已经在MSDN上的Internet上search了几个小时,在SDK代码(Server32.c和Client32.c)中。 在我的具体情况下,我仍然不知道该怎么做。

所以,有人解释我如何使用GetOverlappedResult()(如果我必须使用它)知道如何检查读取操作是否完成,以及在哪里? 甚至,如果有人可以修复我的代码:-)我给了代码,以便每个人都可以testing它(我在网上find很多文档,但几乎总是不准确: – /)

谢谢

[1] http://pastebin.com/fbCH2By8

看看I / O完成端口。 在我看来,这是接收和处理Windows重叠操作通知最有效的方法。 所以基本上你需要在阻塞和非阻塞模式下使用GetQueuedCompletionStatus和GetQueuedCompletionStatusEx,当你准备好处理新的完成事件时,而不是随时调用GetOverlappedResult。 事实上,你甚至可以完全摆脱WaitForMultipleObjects。

另外,你的目标是Unix的味道? 在Solaris中有一个非常相似的抽象。 看看man port_create。

不幸的是,在Linux中没有任何类似的东西。 信号(包括实时)在某种程度上可以用作等待完成对象,但是它们不像Windows和Solaris中的端口那样全面。