为何连接数量多到100个左右时,有些就接受不到数据?

PDD123 2015-08-07 07:03:17
		//Connect 类型是我封装的一个类型,其中的m_socket成员就是套接字
int selcount=0;
SOCKET maxs=0;
timeval timeout;
timeout.tv_sec=0;timeout.tv_usec=50;

fd_set rfd;
fd_set wfd;
fd_set efd;

FD_ZERO (&rfd); //读
FD_ZERO (&wfd); //写
FD_ZERO (&efd); //异常

for(int i=0,count=recvarr.GetSize();i<count;i++)
{
Connect * con=recvarr[i];//recvarr 中的是需要接收数据的连接(已成功建立连接的连接),前面的代码的原因,第一个连接总是在这个数组的最后。
FD_SET(con->m_socket,&rfd);
if(con->m_socket>maxs)
maxs=con->m_socket;
}

for(int i=0,count=conarr.GetSize();i<count;i++)
{
Connect * con=conarr[i];//conarr 中的是正在连接的连接
FD_SET(con->m_socket,&wfd);
FD_SET(con->m_socket,&efd);
if(con->m_socket>maxs)
maxs=con->m_socket;
}

selcount=::select(maxs+1,&rfd,&wfd,&efd,&timeout);
if(selcount>0)
{
DWORD now=::timeGetTime();
for(int i=0,count=conarr.GetSize();i<count;i++)//先处理正在连接的连接
{
Connect * con=conarr[i];
if(FD_ISSET(con->m_socket,&efd))
{
con->m_theLastRecvTime=now;
con->errorOccurred(Connect::ErrorCode_ConnectFailed);
con->set_isNeedDisconnect();//发生异常
}
else if(FD_ISSET(con->m_socket,&wfd))
{
con->m_theLastRecvTime=now;
con->changeState(Connect::ConState_connected);//连接成功
}
}
for(int i=0,count=recvarr.GetSize();i<count;i++)//开始接收数据
{
Connect * con=recvarr[i];//断点A 条件是con->m_socket==XX,XX为指定的套接字
if(FD_ISSET(con->m_socket,&rfd))//连接数 过多时,在recvarr后面的一些套接字在这里的判断就为假
{
con->m_theLastRecvTime=now;
int recvlen=::recv(con->m_socket,Manager.m_RecvBuf,PDDTCPManager::RecvBufLen,0);//断点B 条件是con->m_socket==XX,XX为指定的套接字
//接收数据
if(recvlen>0)
{
con->recv(Manager.m_RecvBuf,recvlen);//处理接收到的数据
}
else
{
con->errorOccurred(Connect::ErrorCode_OtherSideDisconnect);
con->set_isNeedDisconnect();//发生错误
}
}
}
}

以上是我的连接和接收数据部分的代码段,其在一个循环中。

具体症状:
连接一多(数量不定,大约是100个左右),有些连接就无法接收到数据了,而断开一些正常的连接,那无法接收数据的连接又恢复正常!
已经确认了,发送数据、连接 正常,就是接受数据不正常。

调试步骤:
1.我写了一个服务端进行调试,服务端每秒向每一个连接上的客户端发送一个信息。客户端收到信息后显示出来,并想服务端回复一个信息;
2.用调试方式启动一个服务端(只调试服务端);
3.启动一个客户端A,建立一个连接A,此时一切正常,客户端每秒显示出接收到一个信息;
4.设置断点B,此时基本上立马就能触发断点,确认第一个连接的套接字的具体数值x。然后设置断点A,并把两个断点的触发条件设置成 con->m_socket==x;
5.确认了每一次接收数据都能正常触发两个断点之后,把两个断点都禁用掉;
6.启动另一个客服端B,建立100个连接,因为使用的是同一个DLL,所以客户端B中的100个连接,有些正常有些不正常。客户端A中的连接A,看起来一切正常;
7.激活断点B,无法触发断点B;激活断点A,能触发断点A;说明套接字x在“if(FD_ISSET(con->m_socket,&rfd))”处一直判断为假
8.禁用断点A,保持激活断点B;
9.关闭客户端B(关闭100个连接),立马就能触发断点B。

请问,这是什么原因造成的?是否是我忽略了一些相关的细节?

...全文
96 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
PDD123 2015-08-10
  • 打赏
  • 举报
回复
搞定了,关键是fd_set的结构。
//.h
class XXX_fd_set
{
public:
	XXX_fd_set(void);
	~XXX_fd_set(void);
private:
	fd_set * m_pFd_set;
	u_int m_nMaxCount;
public:
	void SetMaxCount(u_int count);
	void Set(SOCKET s);
	void Zero();
	bool IsSet(SOCKET s);
	operator fd_set *() const;
};

//.cpp

XXX_fd_set::XXX_fd_set(void)
:m_pFd_set(0)
,m_nMaxCount(0)
{
}

XXX_fd_set::~XXX_fd_set(void)
{
	if(m_pFd_set)
		delete m_pFd_set;
}

void XXX_fd_set::SetMaxCount(u_int count)
{
	if(count>this->m_nMaxCount)
	{
		fd_set * ls=this->m_pFd_set;
		this->m_pFd_set=(fd_set *)(new char [sizeof(u_int)+sizeof(SOCKET)*count]);
		if(ls)
		{
			this->m_pFd_set->fd_count=ls->fd_count;
			::memcpy(this->m_pFd_set->fd_array,ls->fd_array,sizeof(SOCKET)*ls->fd_count);
		}
		else
			this->m_pFd_set->fd_count=0;
		this->m_nMaxCount=count;
	}
}

void XXX_fd_set::Set(SOCKET s)
{
	if(this->m_pFd_set)
	{
		for(u_int i=0;i<this->m_pFd_set->fd_count;i++)
			if(this->m_pFd_set->fd_array[i]==s)
				return;
		if(this->m_pFd_set->fd_count<this->m_nMaxCount)
		{
			this->m_pFd_set->fd_array[this->m_pFd_set->fd_count]=s;
			this->m_pFd_set->fd_count++;
		}
	}
}

void XXX_fd_set::Zero()
{
	if(this->m_pFd_set)
	{
		this->m_pFd_set->fd_count=0;
	}
}

bool XXX_fd_set::IsSet(SOCKET s)
{
	return this->m_pFd_set!=0 && __WSAFDIsSet(s,this->m_pFd_set);
}

XXX_fd_set::operator fd_set *() const
{
	return this->m_pFd_set;
}
PDD123 2015-08-08
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
select有套接字限制。你需要用别的io模型
非常感谢! 我今天查找了资料,也看了下头文件,有了一点想法,想让改写一个fd_set结构,让其不使用FD_SETSIZE,但是不知道select和__WSAFDIsSet 这两个函数的实现中是否使用了FD_SETSIZE? 我先去试试……
老王爱上猫 2015-08-08
  • 打赏
  • 举报
回复
libevent 或者其它网络库吧,如果是学习的话楼主自便
oyljerry 2015-08-07
  • 打赏
  • 举报
回复
select有套接字限制。你需要用别的io模型
oyljerry 2015-08-07
  • 打赏
  • 举报
回复
select有套接字限制。你需要用别的io模型
oyljerry 2015-08-07
  • 打赏
  • 举报
回复
select有套接字限制。你需要用别的io模型

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧