当前位置: 技术问答>linux和unix
epoll 并发接收数据丢失问题
来源: 互联网 发布时间:2016-05-21
本文导语: 我在windows上通过批处理快速的循环打开了10多个客户端, 客户端一启动马上就向服务器发送数据,通过观察,发现客户端并发的一起向服务器发送数据频率是0.1秒, 大概22字节的样子, 总是有1~2个客户端发送的...
我在windows上通过批处理快速的循环打开了10多个客户端, 客户端一启动马上就向服务器发送数据,通过观察,发现客户端并发的一起向服务器发送数据频率是0.1秒, 大概22字节的样子, 总是有1~2个客户端发送的数据服务器没有收到(receiveSocketData接口就没有被触发)。
注意:我的测试模式是 服务器收到包则会返回一个包, 客户端也是收到一个包才会发送一个包, 因此那2个客户端是第一次发送服务器就没收到而后就不能继续发往服务器了, 他们的连接是通的。
服务器大概这个样子:
startEpoll()
{
socklen_t socklen;
int n = 0;
if ( !isInit() ){
DEBUG_MSG( ">>you must to init epoll.n" );
return -1;
}
if ( listen( listener, lisnum ) == -1 )
{
perror( ">>listen" );
return -1;
}
else
DEBUG_MSG( ">>start server of network is successfully!n" );
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create( m_maxEpollSize );
socklen = sizeof( struct sockaddr_in );
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if ( epoll_ctl( kdpfd, EPOLL_CTL_ADD, listener, &ev) collect();
// 将所有接收到的消息全部压入环形缓冲区
SocketBufferAssigner::getSingleton().getSocketRecvBuffer( socketID )->push( (char*)&buf, recvlen );
//kbp->getExecInterval();
}
/* 处理每个新连接上的数据收发结束 */
return recvlen;
}
注意:我的测试模式是 服务器收到包则会返回一个包, 客户端也是收到一个包才会发送一个包, 因此那2个客户端是第一次发送服务器就没收到而后就不能继续发往服务器了, 他们的连接是通的。
服务器大概这个样子:
startEpoll()
{
socklen_t socklen;
int n = 0;
if ( !isInit() ){
DEBUG_MSG( ">>you must to init epoll.n" );
return -1;
}
if ( listen( listener, lisnum ) == -1 )
{
perror( ">>listen" );
return -1;
}
else
DEBUG_MSG( ">>start server of network is successfully!n" );
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create( m_maxEpollSize );
socklen = sizeof( struct sockaddr_in );
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listener;
if ( epoll_ctl( kdpfd, EPOLL_CTL_ADD, listener, &ev) collect();
// 将所有接收到的消息全部压入环形缓冲区
SocketBufferAssigner::getSingleton().getSocketRecvBuffer( socketID )->push( (char*)&buf, recvlen );
//kbp->getExecInterval();
}
/* 处理每个新连接上的数据收发结束 */
return recvlen;
}
|
class Mutex{...}
class Lock{...}
class ScopeLock{...}
void work_for_client( int client_fd){
ScopeLock( mutexs[ client_fd]);
//now, work for client_fd, it is locked.
}