繁体   English   中英

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

[英]server using an overlapped named pipe : how to use GetOverlappedResult() with ReadFile()?

我已经编写了使用重叠命名管道的服务器和客户端。 我的问题主要是与Readfile()和GetOverlappedResult()有关。

请注意,该程序是测试代码。 它将在以后集成到框架中(我正在将Linux代码移植到使用AF_UNIX地址系列进行套接字连接的Unix)

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

1)主线程打开一个重叠的命名管道,然后在WaitForMultipleObjects()上循环。 WaitForMultipleObjects()等待3个事件:第一个等待客户端连接。 第二个允许我彻底退出程序。 当ReadFile()中有待处理的操作时,发出第三个信号。

2)当客户端连接时,第二个线程启动。 它遍历ReadFile()。

这是服务器代码:

http://pastebin.com/5rka7dK7

我主要使用MSDN doc(使用重叠I / O的命名管道服务器,命名管道客户端),SDK以及Internet上的其他文档来编写该代码。 在[1]中查找客户端代码。 客户端代码需要一些帮助,但就目前而言,我专注于使服务器正常运行。

服务器代码中有4个功能(我忘记了显示错误消息的功能):

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

b)svr_del释放所有资源

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

d)main()函数(主线程),该函数遍历WaitForMultipleObjects()

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

我不明白的是:

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

使用我粘贴的代码,如果客户端发送这24个字节(ReadFile()缓冲区的大小为5个字节),则结果如下。我故意设置该值以测试如果客户端发送的数据大于ReadFile( ) 缓冲)

消息:“礼炮,客户!”

输出:

$ ./server.exe等待客户端... WaitForMultipleObjects:0已连接客户端(1)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字节),但是我不知道读取操作何时完成。

注意:II当ReadFile()失败并出现ERROR_IO_PENDING时,添加了一个printf(),该printf()被无限期调用。

另外,客户端发送2条消息。 上面的一个,另一个3秒后。 永远不会读取第二条消息,并且ReadFile()失败,并显示错误ERROR_SUCCESS ...(准确地说,ReadFile()返回FALSE,而GetLastError()返回ERROR_SUCCESS)

所以,我完全迷路了。 我已经在Internet上的MSDN,SDK代码(Server32.c和Client32.c)中搜索了几个小时。 我仍然不知道该怎么办。

因此,有人向我解释了如何使用GetOverlappedResult()(如果必须使用它)来知道如何检查读取操作是否完成以及在何处? 甚至,即使有人可以修复我的代码:-)我也提供了代码,以便每个人都可以对其进行测试(我在互联网上找到了很多文档,但几乎总是不够精确:-/)

谢谢

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

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

另外,您要定位哪种Unix? 在Solaris中,有非常相似的抽象。 签出man port_create。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM