在epoll et模式 非阻塞io下的一个问题

服务端是用epoll et模式写的echo服务器 ,更改了accept函数返回的fd为NONBLOCK模式
下文代码是客户端的一部分接收和发送代码
乍一看没有什么问题,但是在运行时发生了意料之外的事

while(1)
    {
        printf("Please input: ");
        scanf("%s", buff);
        int ss=strlen(buff);
        int ret= send(sockfd, buff,ss, 0);
        if(ret==-1)
        {
                printf("send error(%d) :%s \n",errno,strerror(errno));
                return -1;
        }
        memset(buff,0,sizeof(buff));
        while(1)
        {       
                ret=recv(sockfd, buff,sizeof(buff), 0);
                if(errno==EAGAIN) break; 
        }
        printf("Recv: %s\n", buff);
    }

在这里插入图片描述

这是截取的一部分执行结果
可以看出来在第一次输入11之后,客户端并没有按照约定输出11,而是输出了一个空字符串
在之后的输入中,客户端输出的数据都是上一次操作输入到客户端中的

猜测问题在于调用send函数发送数据后,因为sockfd是非阻塞的,所以没有等到服务端给客户端返回数据时,客户端就已经输出了缓冲区的数据。很显然,这时缓冲区为空字符串。

while(1)
    {
        printf("Please input: ");
        scanf("%s", buff);
        int ss=strlen(buff);
        int ret= send(sockfd, buff,ss, 0);
        if(ret==-1)
        {
                printf("send error(%d) :%s \n",errno,strerror(errno));
                return -1;
        }
        sleep(1);
        memset(buff,0,sizeof(buff));
        while(1)
        {       
                ret=recv(sockfd, buff,sizeof(buff), 0);
                if(errno==EAGAIN) break; 
        }
        printf("Recv: %s\n", buff);
    }

如上文代码,在服务端recv之前调用sleep(1),即可解决上述问题。
但是感觉用这种方式解决略显随意,希望以后能找到更好的解决方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值