栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

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

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在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: %sn", 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: %sn", buff);
    }

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/300382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号