问一个较难的问题:如何能保证服务器拥有稳定良好的性能?

murouwolf 2004-07-16 09:23:48
我在开发程序的过程中发现有几个问题:
1、怎样可以保证服务器的客户量不会太大?
因为存在这样一个问题,客户太多,会导致服务器发送数据包很缓慢,半天客户端才收到一个包。我曾经试图这样做过

⑴onaccept:
while (g_socklist.size()>MAX_CLIENTNUM)Sleep(100);
SOCKET sk = accept(m_listensock);
⑵onaccept:
SOCKET sk = accept(m_listensock);
if (g_socklist.size()>MAX_CLIENTNUM)
{
shutdown(sk);
closesocket(sk);
}
上面的两种模式我试用都存在问题,我在单机上没发现问题,一旦投入实际使用后,
第一种方法在过一段时间后,会出现,客户端发送任何包都会失败。第二种方法死得更难看,过一段时间后,服务器根本就不响应任何连接,客户端连接直接就失败了。
这个问题十分的困扰我,希望有大侠可以教我。
2、怎样检测服务器数据包的流量???保证在流量达到服务器的限制或者说达到当前网络可以容忍的峰值的时候降低客户数量数量。
这个问题我根本想不到办法,主要原因在于我根本没办法检测是否达到服务器的瓶颈?而且个人对数据包流量这种东西没有概念。
3、第三个问题是我前几天得人启示才想到的,如何保证服务器和客户端没有任何包传输的情况发现物理连接已断开??前几天遇到有个家伙问我如何能够保证在没有RECV没有SEND的情况下检测出连接已断开?我实在无法回答,这令我觉得讨厌。我想过另外开线程来检测,但是这种方法让我觉得不理想,对于一个多线程程序,为了保证对全局连表操作的正确性,而使用互斥量或者其他来保证数据的正确性的时候,不得不让其他线程呆呆地等好长一段时间。

主要就这三问题,希望有大侠慷慨援手,^_^
...全文
192 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
murouwolf 2004-07-19
  • 打赏
  • 举报
回复
服务器已稳定,:),高兴ing..........
danielzhu 2004-07-16
  • 打赏
  • 举报
回复
、怎样检测服务器数据包的流量???保证在流量达到服务器的限制或者说达到当前网络可以容忍的峰值的时候降低客户数量数量。
这个问题我根本想不到办法,主要原因在于我根本没办法检测是否达到服务器的瓶颈?而且个人对数据包流量这种东西没有概念。


___________________________________________
在你的接收程序里边,设置一个startTime = GetTickCount();,一个endTime== GetTickCount();,设定endTime - startTime = 500ms,就把这段时间的总的数据量累加,然后,用总数据量*8*1000/500 = x bps,x就是流量,由于网络上的数据流量变化很快,所以,时间最好小一点!类似于极限的求法
adamx 2004-07-16
  • 打赏
  • 举报
回复
我来up,不过我不是高手。
murouwolf 2004-07-16
  • 打赏
  • 举报
回复
楼上的,你讲了一堆,把偶辛苦找来的高手都吓跑了,连up都没人来:(
elssann 2004-07-16
  • 打赏
  • 举报
回复
有没有人能够确定一下:


当一个WSARecv或者WSASend调用返回WSA_IO_PENDING后,客户端断开。。。
GetQueueCompletionStatus是否一定会返回???
elssann 2004-07-16
  • 打赏
  • 举报
回复
在大量客户连接后,大量的收发数据,
然后客户端断开,这时候很多在完成端口里正在PENDING的IO操作不返回。。

因为我的同一个连接可能同时有WSARecv或者WSASend都在完成端口里PENDING,涉及到引用计数,只有引用计数为0的时候才回收这个连接的资源。。。。如果采取超时检测来关闭也一样达不到这个目的,即使我认为这个SOCKET超时了,主动对这个SOCKET进行closesocket,但是在这之前调用成功后正在完成端口里PENDING的WSARecv或者WSASend还是不会返回。。。。这样引用计数没有机会减掉,还是无法回收这个连接的资源,,,真是郁闷死了。。。
今天采用CancelIo发现也没作用,,,因为CancelIo只能取消由本线程发出的IO操作,,
FUCK!!!


现在问题主要在这上面:

当我的一个WSARecv或者WSASend的调用返回WSA_IO_PENDING后,客户端断开,GetQueueCompletion不返回。。。。..

也不是所有的都不返回,在我客户端连接3000个左右,服务器的收发流量在160M BPS/S的情况下,如果把客户端关闭,会有几百个不返回。。。然后重复连接重复断开,就导致累计的越来越多。。。
fengge8ylf 2004-07-16
  • 打赏
  • 举报
回复
关注
sailor_2002 2004-07-16
  • 打赏
  • 举报
回复
内存在涨,我觉得你是否存在资源没有释放,造成了内存泄漏呢,不一定是客户端太多的问题,可能是客户端断开后资源没有释放的问题
murouwolf 2004-07-16
  • 打赏
  • 举报
回复
to:PiggyXP
1、我也不知道到底有多少(主要是我想有些死掉的连接,但我并不知道,所以计算出来的结果很可能是不准确的),反正我内存一直都在长,剧光火,长个三天或者一周左右,程序就挂了,限制了连接,在本机测试可以无问题,放到服务器就有问题
2、流量应该可以算,怎么才知道到了服务器的瓶颈不知道啊
3、一直都有数据包传输的,不可能有停下来的时候,也就是说一直都是很忙的,除非另外开线程专门循环检测每一个客户端的状态,这个我觉得很麻烦啊,而且对于完成端口,把一个发送或者接收操作挂接上去后,GetQueuedCompletionStatus会不会有返回根本就没法预料(我是这么理解的,如果每个都返回了,应该内存不会无限制增长吧?)
PiggyXP 2004-07-16
  • 打赏
  • 举报
回复
1。 楼主的服务器到底有多少个客户端?

完成端口我以前测试的时候响应 7000 个client连接都是丝毫没有问题的

2。 数据包流量就只有楼主自己想办法计算了,

数据包总大小 / 时间

3。 如果可以监听FD_CLOSE事件就监听之,不能监听就只有心跳包了呵呵

你可以在一没有数据传输的时候就开始计时,到了比如10秒都没有数据传输

就可以发送一个心跳包
自由的风 2004-07-16
  • 打赏
  • 举报
回复
使用QOS来管理
murouwolf 2004-07-16
  • 打赏
  • 举报
回复
我用的就是完成端口,呵呵,

关于网络是否断开,我以前的方法是网络闲时发“心跳包”,一种小的数据包,不成功就网络断开了。

这个我怎么知道网络闲????
kufan 2004-07-16
  • 打赏
  • 举报
回复
服务器支持大量client的连接可以使用完成端口(IOCP)在论坛上搜一下很多

关于网络是否断开,我以前的方法是网络闲时发“心跳包”,一种小的数据包,不成功就网络断开了。
murouwolf 2004-07-16
  • 打赏
  • 举报
回复
to:kufan(我是真的不会表达我的爱)
可以讲得详细点吗?或者给个连接?

to:rtdb(东临碣石) ( )
关于这个问题,我是为了防止有用户恶意的连接,比如对方就建立一个空连接,啥事都不做,那咋办呢?
rtdb 2004-07-16
  • 打赏
  • 举报
回复
呵,开发服务器程序,要求是很高的,慢慢积累经验吧。
比如客户太多的问题,
你根本不应在SOCKET级处理。
就在SOCKET级拒绝,
用户端会认为是网络不好,还是要重试连进来,
结果就是服务器更忙了。

若是发现用户过多,应回复一个包,
通知用户,并禁止用户在一段时间内再重新来连接。

kufan 2004-07-16
  • 打赏
  • 举报
回复
IOCP、HeartBeat测试
murouwolf 2004-07-16
  • 打赏
  • 举报
回复
怎么解决的?我很想知道啊
elssann 2004-07-16
  • 打赏
  • 举报
回复
偶的问题偶已经解决了。。。。
fengge8ylf 2004-07-16
  • 打赏
  • 举报
回复
服务器怎样检验数据包的合法性 如果有一个连接乱发包的话 那怎么办
fengge8ylf 2004-07-16
  • 打赏
  • 举报
回复
to elssann() 考虑控制收发数据的速度 发送我喜欢用send 不用wsasend

18,356

社区成员

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

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