socket网络编程中返回值的含义

正文

最近学习socket网络编程,总结一下其中recv和send的返回值以及对应的含义

recv()方法

模型:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数:

  • sockfd:创建的文件描述符fd
  • buf:接收数据的缓冲区
  • len:接收数据的长度
  • flags:表示信息,默认设置为0

当应用程序调用recv接收数据的时候,recv函数会等待sockfd中发送数据的缓冲区的协议发送完数据,如果在等待过程中出现网络错误,则会返回SOCKET_ERROR。如果sockfd中的缓冲区中没有数据或者协议已经发送完数据,则recv会检查sockfd的接收缓冲区,如果该缓冲区正在接收数据,则recv会一直等待,直到缓冲区接收数据完毕,之后recv将数据从缓冲区拷贝一份至buf中。注意,数据是通过协议转发的,recv()只是将数据从缓冲区拷贝过来。如果recv()在拷贝数据时出现错误,则返回SOCKET_ERROR,如果在协议传输数据中出现网络错误,则返回0.

阻塞与非阻塞模式下recv()的**返回值没有区别!!!**都是:

  • <0:出错
  • =0:对方调用了close()来关闭连接
  • >0:接收到的数据大小

**注意:返回值<0时是有很多含义的,具体还要看此时的errno的值。比如返回值<0,并且errno==EINTR||errno==EWOULDBLOCK||errno==EAGAIN,此时人情连接时正常的,继续接收**

但是在阻塞模式下就不会出现这种情况,因为这种情况默认也是阻塞。

具体的返回值类型:

  • >0:成功执行时,返回接收到的字节数

  • =0:若另一端已关闭连接则返回0,这种关闭是对方主动且正常的关闭

  • <0:失败,返回-1,且errno被设置为以下的某个值

    • EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
    • EBADF:sockfd不是有效的描述符
    • ECONNREFUSE:远程主机拒绝网络连接
    • EFAULT:内存空间访问出错
    • EINTR:操作被信号中断
    • EINVAL:参数无效
    • ENOMEM:内存不足
    • ENOTCONN:与面向连接关联的套接字尚未被连接上
    • ENOTSOCK:sockfd不是套接字

send()方法

模型:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数:

  • sockfd:创建的sockfd文件描述符
  • buf:发送数据所在的数据区
  • len:发送数据的长度
  • flags:标志位,默认设置为0

当程序使用send()方法时,send()会首先检查协议sockfd中的发送缓冲区中是否有数据发送,send()会比较发送数据的buf长度和sockfd发送数据的缓冲区长度,如果len大于sockfd的发送长度,则send()返回SOCKET_ERROR,如果发送缓冲区的大小足够,则将数据buf中的数据发送至发送缓冲区中,确认send()函数将数据拷贝至发送缓冲区中。另外,如果send()检测发送缓冲区有数据但是还未发送,就比较该缓冲区的剩余空间和len的大小,如果len大于剩余空间,就一直等待,直到缓冲区中的数据发送完为止,如果len小于缓冲区的剩余大小,那么九江待发送的数据拷贝至缓冲区中,如果send函数copy数据成功,就返回实际copy的字节数,如果send()函数在拷贝数据时出现错误,那么send()就返回SOCKET_ERROR;如果send()在等待协议传送数据时网络断开的话,那么send()函数也返回SOCKET_ERROR

(需要注意的是,默认情况下send()函数只是将数据拷贝至发送缓冲区中,就返回了,此刻数据不一定立刻就发送至接收端,若想数据在发送缓冲区中不做合包立刻发送,需要利用setsockopt()函数对套接字进行设置)

返回值作用与上文recv()方法相同。

总结

无论是send()还是recv()方法,都是对数据的接收缓冲区和发送缓冲区进行拷贝的过程,真正发送数据的是协议功能。


标题:socket网络编程中返回值的含义
作者:staymeloo7
联系方式:staycoolsun@gmail.com

    评论
    0 评论
avatar

取消