3. recv和W S A R e c v
对在已连接套接字上接受接入数据来说, r e c v函数是最基本的方式。它的定义如下:

int recv(
     SOCKET s,
     char FAR * buf,
     int len,
     int flags
    );
第一个参数s,是准备接收数据的那个套接字。第二个参数b u f,是即将收到数据的字符缓冲,而l e n则是准备接收的字节数或b u f缓冲的长度。最后, f l a g s参数可以是下面的值: 0、M S G _ P E E K或M S G _ O O B。另外,还可对这些标志中的每一个进行按位和运算。当然, 0表示无特殊行为。M S G _ P E E K会使有用的数据复制到所提供的接收端缓冲内,但是没有从系统缓
冲中将它删除。另外,还返回了待发字节数。
消息取数不太好。它不仅导致性能下降(因为需要进行两次系统调用,一次是取数,另一次是无M S G _ P E E K标志的真正删除数据的调用),在某些情况下还可能不可靠。返回的数据可能没有反射出真正有用的数量。与此同时,把数据留在系统缓冲,可容纳接入数据的系统空间就会越来越少。其结果便是,系统减少各发送端的T C P窗口容量。由此,你的应用就不能获得最大的流通。最好是把所有数据都复制到自己的缓冲中,并在那里计算数据。前面曾介绍过M S G _ O O B标志。有关详情,参见前面“带外数据”的内容。

在面向消息或面向数据报的套接字上使用r e c v时,这几点应该注意。在待发数据大于所提供的缓冲这一事件中,缓冲内会尽量地填充数据。这时, r e c v调用就会产生W S A E M S G S I Z E错误。注意,消息长错误是在使用面向消息的协议时发生的。流协议把接入的数据缓存下来,
并尽量地返回应用所要求的数据,即使待发数据的数量比缓冲大。因此,对流式传输协议来说,就不会碰到W S A E M S G S I Z E这个错误。
W S A R e c v函数在r e c v的基础上增加了一些新特性。比如说重叠I / O和部分数据报通知。
W S A R e c v的定义如下:

int WSARecv(
       SOCKET s,
       LPWSABUF lpBuffers,
       DWORD   dwBufferCount,
       LPWORD  lpNumberOfBytesRecved,
       LPWSAOVERLAPPED lpOverlapped,
       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE
      );
      
参数s,是已建立连接的套接字。第二和第三个参数是接收数据的缓冲。l p B u ff e r s参数是一个W S A B U F结构组成的数组,而d w B u ff e r C o u n t则表明前一个数组中W S A B U F结构的数目。
如果接收操作立即完成, l p N u m b e r O f B y t e s R e c e i v e d参数就会指向执行这个函数调用所收到的字节数。l p F l a g s参数可以是下面任何一个值: M S G _ P E E K、M S G _ O O B、M S G _ PA RT I A L或者对这些值进行按位和运算之后的结果。M S G _ PA RT I A L标志使用和出现的地方不同,其含
义也不同。对面向消息的协议来说,这个标志是W S A R e c v调用返回后设置的(如果因为缓冲空间不够导致整条消息未能在这次调用中返回的话)。这时,后面的W S A R e c v调用就会设置这个标志M A S G _ PA RT I A L,直到整条消息返回,才把这个标志清除。如果这个标志当作一个输入参数投递,接收操作应该在一收到数据就结束,即使它收到的只是整条消息中的一部分。
M S G _ PA RT I A L标志只随面向消息的协议一起使用。每个协议的协议条目都包含一个标志,表明是否支持这一特性。有关详情,参见第5章。l p O v e r l a p p e d和l p C o m p l e t i o n R O U T I N E参数用于重叠I / O操作

4. WSARecvDisconnect
这函数与W S A S e n d D i s c o n n e c t函数对应,其定义如下:
int WSARecvDisconnect( 
            SOCKET s,
            LPWSABUF lpOUTboundDisconnectData
           );
和W S A S e n d D i s c o n n e c t函数的参数一样,该函数的参数也是已建立连接的套接字句柄和
一个有效的W S A B U F结构(带有收到的数据)。收到的数据可以只是断开数据。这个断开数据是另一端执行W S A S e n d D i s c o n n e c t调用发出的,它不能用于接收普通数据。另外,一旦收到这个数据, W S A R e c v D i s c o n n e c t函数就会取消接收远程通信方的数据,其作用和调用带有S D _ R E C V的s h u t d o w n函数相同。
5. WSARecvEx
W S A R e c v E x函数是微软专有的Winsock 1扩展,除了f l a g s参数是按值引用外,其余和r e c v函数是一样的。它允许基层的提供者设置M S G _ PA RT I A L标志。该函数的原型如下:

int PASCAL FAR WSARecvEx(
             SOCKET s,
             char FAR * buf,
             int len,
             int * flags
            );
            


如果收到的数据不是一条完整的消息, f l a g s参数中就会返回M S G _ PA RT I A L标志。对面向消息的协议(即非流协议)来说,这个标志比较有用(即非流协议)。在M S G _ PA RT I A L标志被当作f l a g s参数的一部分投递,而且收到的消息又不完整时,调用W S A R e c v E x,就会立即
返回收到的那个数据。如果提供的接收缓冲容纳不下整条消息, W S A R e c v E x就会失败,并出现W S A E M S G S I Z E 错误,剩下的数据也会被截掉。注意, M S G _ PA RT I A L 标志和W S A E M S G S I Z E错误之间的确区别是:有了这个错误,即使整条消息到达接收端,但由于提
供的数据缓冲太少,也不能对它进行接收。M S G _ P E E K 和M S G _ O O B标志还可以和W S A R e c v E x一起使用。

Posted on 2006-09-07 22:32 艾凡赫 阅读(803) 评论(2)  编辑 收藏 引用 所属分类: 基础知识网络编程

Feedback

# re: windows网络编程九  回复  更多评论   

2006-09-07 22:04 by 爱饭盒
测试

# re: windows网络编程九  回复  更多评论   

2011-06-08 11:59 by 外网
@爱饭盒
万维网

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理