WSARecv()和lpNumberOfBytesRecvd参数

时间:2015-02-27 03:06:21

标签: c++ sockets iocp

WSARecv()的{​​{3}}对lpNumberOfBytesRecvd参数说了以下内容:

  

指向此调用接收的数据的数字(以字节为单位)的指针   接收操作立即完成。

     

如果lpOverlapped参数不为NULL,则对此参数使用NULL   避免可能的错误结果。此参数可以为NULL   仅当lpOverlapped参数不为NULL时。

我正在使用IOCP,因此lpOverlapped不能NULL,同时WSARecv()可以立即完成。因此,如果WSARecv()立即完成,如果lpNumberOfBytesRecvdNULL,我怎么想知道读取了多少字节?或者文档是否意味着我可以NULL使用lpNumberOfBytesRecvd,但我不必这样做?

2 个答案:

答案 0 :(得分:1)

当重叠的WSARecv()IO_PENDINGSUCCESS完成时,完成数据包排队等待IOCP,请参阅this MSDN article for details

使用Vista或更高版本,您可以通过调用套接字SetFileCompletionNotificationModes()并传递FILE_SKIP_COMPLETION_PORT_ON_SUCCESS来更改此信息(请注意,您可以在文档中将文件读作插槽,文件句柄的概念直接转换为插座)。

如果您启用完成端口跳过,那么当WSARecv()立即返回数据(即SUCCESS返回而不是IO_PENDING返回)时,您必须直接在{ {1}}呼叫网站,因为您将无法获得完成数据包。

请注意,启用"跳过完成端口"处理对于减少上下文切换非常有用,但您现在需要以两种方式处理完成:直接(当WSARecv()返回WSARecv()时)或在正常完成处理程序中(当SUCCESS返回时)错误,错误为WSARecv())。而在两个结果都产生完成包之前。

所以,回答你的问题......

除非您已启用"跳过完成端口"处理没有理由在IO_PENDING的呼叫站点使用lpNumberOfBytesRecvd的值,因为即使调用返回WSARecv()因为数据已经可用,您仍将获得排队的完成你必须以通常的方式处理的IOCP。

如果且仅在您启用了#34;跳过完成端口"您应该处理通过调用SUCCESS返回的数据进行处理,该调用会在您获得WSARecv()结果时返回SUCCESS

答案 1 :(得分:0)

文档只是说明了在这些参数上使用NULL的一些规则,声明您必须使用NULL任何情况。您可以根据需要始终将这些参数正确指向有效变量。