epoll 中使用et模式,recv获取数据不全问题。
本帖最后由 dragonsea 于 2013-09-09 16:02:48 编辑 epoll中使用ET模式,使用recv获取数据。存在以下问题“
1.已经使用while循环取,但是提交8052字节的数据时,获取不全,一般能获取2000多字节。但是在recv方法下面调用sleep(1) 就能获取完整数据。请问这是为什么?如何修改代码能获取全部数据?
2.在调用recv方法前,检测errno的值为11(EAGAIN),调用recv后,无论是否能正常获取数据,哪怕recv返回值大于0,errno也是11 .也就是 EAGEIN. 为什么? errno的值不会因为最近一次recv成功调用,而改变值吗?
3.会不会出现这种情况,客户端发了个很大的包。在传输的时候,可能需要分包传输。当第一个包到达的时候,epoll触发了EPOLLIN事件,此时进行recv获取数据,得到第一个包。但是没有达到指定的长度,再次recv获取,这个时候第二个包还未到达。结果获取的长度为 -1 .
代码如下:
//读取数据
void recvData(int fd)
{
memset(buffer, 0, BUFFER_LEN);
int len;
int data_len = 0;
memset(buffer, 0, BUFFER_LEN);
cout << "before recv errno: " << errno << endl;
while (1)
{
len = recv(fd, &buffer[data_len], 10, MSG_DONTWAIT);//MSG_PEEK
if (len > 0)
{
data_len += len;
}
cout << "\n=============\n len:" << len << "\n strlen(buffer):" << strlen(buffer) << "\n" << "errno:" << errno << "\n" << buffer << endl;
//sleep(1); //把注释去掉后,就可以正常读取了
if (len == -1)
{
if (errno == EAGAIN)
{
break;
}else if (errno == EINTR)
{
continue;
}
}
}
}
errno:11
TRACE Cardura Kaufen | Für Schweiz, Deutschland, Osterreich, Holland
[url=http
=============
len:10
strlen(buffer):90
errno:11
TRACE Cardura Kaufen | Für Schweiz, Deutschland, Osterreich, Holland
[url=http://health-
=============
len:10
strlen(buffer):100
errno:11
TRACE Cardura Kaufen | Für Schweiz, Deutschland, Osterreich, Holland
[url=http://health-seller.net epoll
[解决办法]
抓包工具看看吧! 确认是否都完全发送过来了
有没有丢包!
对于网路方面的,请学会用wireshark抓包工具
[解决办法]