- 论坛徽章:
- 0
|
我参考lighttpd写了一个基于epoll的多进程服务器,epoll采用ET非阻塞工作方式,epoll_wait和监听连接的代码都是在main线程中
(使用epoll的方式基本同lighttpd,看过lighttpd源码的应该清楚以上工作方式,不同的是自己加了多线程来处理读取数据后的业务逻辑)
当客户端发送的小流量数据时,epoll能正常工作
但当客户端发送大的流量数据时,比如连续发送大于30000个字节的数据,epoll读取数据就有问题,
是不是因为读取数据来不及导致epoll接受缓冲区不够用了?
我的read函数是这样的:
int FDRecv(FDConnection *con, char *buf, int bufsize)
{
int len = 0;
int toread;
int s = 0;
int fd = con->fd;
if (ioctl(fd, FIONREAD, &toread))
{
return -1;
}
len = read(fd, buf, bufsize);
if ( len < 0)
{
printf("read socket %d error: %s\n", fd, strerror(errno));
con->is_readable = 0;
// 由于是非阻塞模式,当errno为EAGAIN时,表示当前缓冲区无数据可读了
if (EAGAIN == errno)
{
return 0;
}
if (EINTR == errno)
{
con->is_readable = 1;
return 0;
}
con->FDConnectionSetReadState(READ_DRIVE_FD_ERROR);
return -1; // -1出错
}
else if (0 == len) // 客户端关闭了连接
{
con->is_readable = 0;
con->FDConnectionSetState(CON_STATE_READ);
con->FDConnectionSetReadState(READ_DRIVE_FD_CLOSE);
return -2; // -2关闭连接
}
else if (len < toread) // 读取的比预期的要小,则需要等待下一次读事件
{
con->is_readable = 0;
}
//printf("toread = %d, len = %d\n", bufsize, len);
return 0;
}
每当epoll_wait一个读事件,则调用该函数。以上读取代码段有问题吗??
ps:当采用gdb单步调试时,epoll工作又没问题,郁闷。。
[ 本帖最后由 butoo 于 2009-10-29 20:41 编辑 ] |
|