recv函数和send函数返回值错误处理

本文中分析的都是非阻塞态的socket错误代码,因为阻塞态也不会出现EWOULDBLOCK错误。

1、recv函数:

返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续接收。

socket设置为非阻塞的时候,recv返回错误时才会有 errno == EWOULDBLOCK || errno == EAGAIN两种情况;

  • #define EWOULDBLOCK    EAGAIN 

          因为宏定义EWOULDBLOCK和 EAGAIN ,所以二者等价;

  • EWOULDBLOCK,WOULD英文语法是表示过去将来式,表示本来应该。。。;

        放在此处的意思是,本来应该阻塞,却没有阻塞。(也就是并没有发生阻塞,原因是设置了非阻塞态,也就说这个错误是在非阻塞态时才会有的)

EWOULDBLOCK的意思是如果你不把socket设成非阻塞(即阻塞)模式时,这个读操作将阻塞,也就是说数据还未准备好(但系统知道数据来了,所以select告诉你那个socket可读)。使用非阻塞模式做I/O操作的细心的人会检查errno是不是EAGAIN、EWOULDBLOCK、EINTR,如果是就应该重读,一般是用循环。如果你不是一定要用非阻塞就不要设成这样,这就是为什么系统的默认模式是阻塞。

int foo(SOCKET socket, char *buff, int length)
{
    int nleft, nread;
    nleft = length;
    while(nleft > 0)
    {
        nread = recv(socket, buff, nleft,0);        
        if(nread == 0)//对端socket调用close()关闭
        {
            printf("%s", strerror(errno));
            return -1;
        }
        if(nread < 0)
        {
            if(errno == EINTR ||errno == EAGAIN ||errno == EWOULDBLOCK)
                continue;
            printf("%s", strerror(errno));
            return -1;
        }
        nleft -= nread;
        buff += nread;
    }
    return(length - nleft);
}

 如示例,recv函数是不能通过返回值来判断读满了buff个数据的,因为recv返回0表示,对端socket正常关闭了。

所以,需要通过判断未读的字节数>0?来解决这个问题。

2、send函数

int foo(SOCKET socket, char *buff, int length)
{
    int nleft, nsend;
    nleft = length;
    while(nleft > 0)
    {
        nsend = send(socket, buff, nleft,0);        
        if(nsend == 0)//对端socket调用close()关闭
        {
            printf("%s", strerror(errno));
            return -1;
        }
        if(nsend < 0)
        {
            if(errno == EINTR ||errno == EAGAIN ||errno == EWOULDBLOCK)
                continue;
            printf("%s", strerror(errno));
            return -1;
        }
        nleft -= nsend;
        buff += nsend;
    }
    return(length - nleft);
}

3、附录

recv函数返回值及errno值

 

send函数errno值

 

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值