recv或者recvfrom

recv和recvfrom都是用来接受来自的网络的数据。来看看它们的原型:

 

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

int recvfrom(
  SOCKET
s,                  
  char FAR* buf,             
  int len,                   
  int flags,                 
  struct sockaddr FAR *from, 
  int FAR *fromlen           
);

 

这是在windows下面的定义。在linux下面的定义只是将SOCKET改成int,那么在linux下面的原型是这样:

 

int recv(
  int
s,      
  char FAR *buf, 
  int len,       
  int flags      
);

 

int recvfrom(
  int
s,                  
  char FAR* buf,             
  int len,                   
  int flags,                 
  struct sockaddr FAR *from, 
  int FAR *fromlen           
);

 

 

其实要是看看windows中SOCKET的定义,就知道它们几乎是完全相同了,为什么是几乎?因为还是有点小区别,linux下面是int类型,而windows下面是unsigned int。下面就是windows中SOCKET的定义:

typedef UINT_PTR        SOCKET;

typedef unsigned int UINT_PTR, *PUINT_PTR;

 

插一句,在linux下面这里的int s, 其实代表的是文件描述符。在linux中所有的设备,如磁盘,光驱,U盘甚至我们这里的讨论的网络也都被看作是文件。

 

我们看看这两个函数在功用上的共同点和不同点:

 

共同点:

1. 都是用来接受来自网络的数据

 

2. 都可以 接受面向连接的流式套接字的 和 接受无连接的数据报套接字 的数据

 

3. 在成功接受到数据后,返回值都是实际接受的字节数; 套接字关闭时,返回都为0; 接受出错时,windows下面都返回SOCKET_ERROR , linux下面都返回-1, 其实你要是感兴趣可以查看SOCKET_ERROR 定义,它的值也是-1;

关于这里的“套接字关闭”需要注意,2个函数在用在流式套接字和数据报套接字时,套接字表示的含义不一样,前者表示客户端套接字,而后者表示的是自己的套接字。

 

4. 如果套接字为阻塞的,在系统缓冲中没有数据的情况下,都将阻塞;如果套接字为非阻塞的,在系统缓冲中没有数据的情况下,都将立即返回,返回值在linux下为-1, errno被设置为EWOULDBLOCK,在windows下面返回SOCKET_ERROR, 通过WSAGetLastError返回WSAEWOULDBLOCK.

 

5. 如果用在流式套接字,则2者的操作是:将已在内核缓冲区的数据拷贝到应用程序自己的缓冲区,拷贝的最大的长度为调用函数时传入的缓冲区的长度,注意这里的长度不一定等于实际缓冲区的长度,可以小于缓冲区的长度,但是绝对不能大于,为什么不能大于,也许你比我更清楚。例如下面这段代码:

char szRecvBuf[1024] = { 0 };

recv( sockServer, szRecvBuf, 256, 0 );

这里虽然定义的缓冲区的长度为1024但是接受的时候只用其中的256. 如果内核缓冲区当时有10个字节,那么这次调用立刻返回,szRecvBuf被填充了10字节,返回值是10。 如果内核缓冲区有1500个字节,那么szRecvBuf将被填充256个字节,返回值就是256.                               

如果是数据报套接字,在内核缓冲区中的数据小于要求长度(这里是256)的情况下,和流式套接字结果一样。但是大于的情况就不一样了,首先将填充256到szRecvBuf中,并且产生一个WASEMSGSIZE的错误,并且剩下的部分被丢弃。假如内核缓冲区的数据为1000字节,那么前面的256被填充到szRecvBuf中,后面的1000-256将被丢弃。

recvfrom的执行效果也是同样的。

上面的结论是结合msdn和实际的测试得出的。

recvfrom的实际效果也是这样。

 

不同点:

1. 函数参数不一样

 

未完待续…

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.

    分享到:

留言

你的邮箱是保密的 必填的信息用*表示