服务器程序为Socket Sever,绑定12005端口,启动就Listen,然后客户端不停的连接、断开,在每天4点服务器程序自动关闭后,又由另外一个守候程序打开。服务器运行8-9天后,客户端不能连接了,连接的客户端也请求不了数据,就是说服务器程序不接受SOCKET连接了,发送的数据在OnReceive()不能接受了,在这个时间用远程登录可以登录到服务器,CPU也是4%左右,自己的服务器程序用内存也是不到10M(曾经到过70M也没问题),数据的一条线城也没有堵塞(当时自己打开SQL2000企业管理器查看到的),关闭自己服务器程序,客户端又可以连接上来,但是过了2个小时又是上面的情况,这次关闭自己服务器程序也不能连接了,只好将操作系统关闭,重新启动服务器机器,重起后可以了。又要运行到8-9天后才发生重复的事情、、、,好奇怪呀,已经连续发生4次了,找不到原因,自己认为
1、是不是操作系统的端口8-9天后用完了?如果是
2、内存用完了?(1G系统内存,在资源管理器看到是一直稳定到830M左右)
1、是不是操作系统的端口8-9天后用完了?如果是
2、内存用完了?(1G系统内存,在资源管理器看到是一直稳定到830M左右)
中直接用了Close();
这样一来,就会有许多死连接,服务器端无法清除。
Windows 2000 pro(SP4)上大约能创建2200个Socket(实测数据!),一旦达到这个数量就无法创建新的Socket,当然不会接受连接了
C/S之间没有数据发送的时候要发送一些在线包,比如说,没有数据传输时每20秒发送一个空格
Server端对每个连接定时检测,大概象下面这样:
OnRecv()
{
last_recv_time = GetTickCount();
//do recv() here
}OnTimer()
{
if(GetTickCount()-last_recv_time>35000)//close connection any way after 35 seconds' idle
{
closesocket(s)
}
}
这样一来,就会有许多死连接,服务器端无法清除。
Windows 2000 pro(SP4)上大约能创建2200个Socket(实测数据!),一旦达到这个数量就无法创建新的Socket,当然不会接受连接了
对于在线和下线的时间我有专门记录来查询的,一天一般不会超过20个用户异常断线(比如网线掉线等),所以说不可能达到您所说的2200个SOCKET的问题,而且我在每天4点时服务程序会自动关闭然后由守侯程序打开,目的也是为了释放一些死连接和重新连接数据库,是不是这样也无法释放那些死连接?一直到8天后死连接达到了极限,就才有那样的问题了?但是也是不到200个死连接呀?
一天一般都有300-400个连接,同时在线不超过100个。8天就是达到了2500个连接左右,是不是服务器的Close() SOCKET不成功,我是在OnClose()中直接Close()的。 hjunxu(hjun) ( )
有没有看一下出问题的时候端口情况是怎么样的阿?请问如何查端口的情况呀?
数据库数据在转发给socket??为什么客户端不直接连数据库捏?难道又是因为lisence
请问如何socket连接加心跳包检测呀?不是数据库的问题,也不是licence的问题。每次要读写数据库就连接一次,读写完就断开连接,这样会产生效率的问题的,应该对数据库长 连接才好吧。
这个可以参照楼上: DoItFreely(Freely) ( ) 信誉:95 的方法做
客户端要有重连机制
有没有看一下出问题的时候端口情况是怎么样的阿?
---------------
netstat -na就好了.
检查服务器里的资源分配和释放代码,
因为你每天CLOSE,所以不可能是SOCKET导致的问题,
进程退出,进程的SOCKET HANDLE资源就被完全释放,
{
BOOL bConnDropped = FALSE;
INT iRet = 0;
BOOL bOK = TRUE;
if (m_hSocket == INVALID_SOCKET)
return TRUE; struct timeval timeout = { 0, 0 };
fd_set readSocketSet;
FD_ZERO(&readSocketSet);
FD_SET(m_hSocket, &readSocketSet);
iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
bOK = (iRet > 0);
if(bOK)
{
bOK = FD_ISSET(m_hSocket, &readSocketSet);
}
if(bOK)
{
CHAR szBuffer[1] = "";
iRet = ::recv(m_hSocket, szBuffer, 1, MSG_PEEK);
bOK = (iRet > 0);
if(!bOK)
{
INT iError = ::WSAGetLastError();
bConnDropped = (( iError == WSAENETRESET) ||
(iError == WSAECONNABORTED) ||
(iError == WSAECONNRESET) ||
(iError == WSAEINVAL) ||
(iRet == 0));
}
}
return(bConnDropped);}心跳包检测函数。
一段时间之后,比如5分钟,如果活动的地址数(IP:Port)远小于“在线数”,说明有很多死连接
你说的问题我不太清楚,不过我前两天遇到一个问题我做的是远程控制系统,上位机操作系统是WINDOWS 2000下位机是WINDOWS 98我用上位机发具体的命令控制下位机的程序运行,结果我的下位机程序会在几个小时内死机,后来同事说有可能是资源的事情,我查了一下没有资源泄露啊(通过VC调试器)可是后来他帮我仔细的检查了一下代码,才发现真是问题多多,希望这些对你有帮助.
呵呵我的下位机硬盘512M处理器是奔三的内存32M!!!我想和你的服务器相比时间是很成比例的.
同情!!!!!!
怎样保证长连接捏。
我这么设想吧,设置数据库连接和执行时间,如果连接超时则连接失败,
如果执行超时,则认为这次连接已断开,继续重新连接,
这些是监测是否断,要防止断,我想还得往数据库发语句来检测吧。
我也不是很清楚什么是长连接,但是我的客户端连上后如果一个小时不操作,然后再请求或发送数据也是很正常的,说明SOCKET是没断的,而且数据库也是连接上的,这不知道算不算是长连接,数据库读取用的是OLEDB技术。
flashboy(爱写程序的小绵羊) 服务器端不管有多少用户来连,只会开一个侦听端口的。肯定不是端口问题, 有可能是SOCKET句柄未正常关闭引起的。如果实在不行,就等问题出现的时候,你再连接的时候,抓一下TCP的3次握手包, 看是哪一次握手出了问题。
有可能是SOCKET句柄未正常关闭引起的 、、、
我在CSocket的OnClose()函数中直接Close(),这是不是正常关闭了。
抓一下TCP的3次握手包, 看是哪一次握手出了问题
请问如何抓呀?
一段时间之后,比如5分钟,如果活动的地址数(IP:Port)远小于“在线数”,说明有很多死连接CommView在那里找到?还是DOS命令?
我的操作系统是Win2003 SP1加MSSQL2000 SP4。
建议你不要定时关闭,就是不要守护进程,
让它连续运行,看到第几天出问题
我以前试过,一天就有问题了,后来重写了服务器的代码,加上守侯程序处理,就变成了8-9天的时间了。
OLEDB技术如果是几十个小时长时间连接肯定也会断的不过,其实断了也没什么,做个超时检测,如果超时,则认为断了重关闭,再连。
-----------------------------
问题很明显,肯定是端口用完了,telnet证明你的监听是有效的,但不是能accept了,就是分配不到端口了,关闭时你多半没有调用closesocket(),closesocket之前最好还调用一个shutdown(s, SD_BOTH)来温柔关闭。
netstat -a 看看,是否有许多 TIME_WAIT状态的连接没有释放占用了端口
TCP kcrjserver:http kcrjserver:0 LISTENING
TCP kcrjserver:epmap kcrjserver:0 LISTENING
TCP kcrjserver:microsoft-ds kcrjserver:0 LISTENING
TCP kcrjserver:1025 kcrjserver:0 LISTENING
TCP kcrjserver:1033 kcrjserver:0 LISTENING
TCP kcrjserver:ms-sql-s kcrjserver:0 LISTENING
TCP kcrjserver:3389 kcrjserver:0 LISTENING
TCP kcrjserver:11111 kcrjserver:0 LISTENING
TCP kcrjserver:12005 kcrjserver:0 LISTENING
TCP kcrjserver:1034 kcrjserver:ms-sql-s ESTABLISHED
TCP kcrjserver:ms-sql-s kcrjserver:1034 ESTABLISHED
TCP kcrjserver:ms-sql-s kcrjserver:1689 ESTABLISHED
TCP kcrjserver:1689 kcrjserver:ms-sql-s ESTABLISHED
TCP kcrjserver:netbios-ssn kcrjserver:0 LISTENING
TCP kcrjserver:3389 KCRJ:1224 ESTABLISHED
TCP kcrjserver:12005 KCRJ:1271 ESTABLISHED
UDP kcrjserver:microsoft-ds *:*
UDP kcrjserver:isakmp *:*
UDP kcrjserver:1036 *:*
UDP kcrjserver:1148 *:*
UDP kcrjserver:ms-sql-m *:*
UDP kcrjserver:4500 *:*
UDP kcrjserver:38037 *:*
UDP kcrjserver:ntp *:*
UDP kcrjserver:bootps *:*
UDP kcrjserver:bootpc *:*
UDP kcrjserver:ntp *:*
UDP kcrjserver:netbios-ns *:*
UDP kcrjserver:netbios-dgm *:*
UDP kcrjserver:2051 *:*
UDP kcrjserver:2535 *:*
这是客户端的:Microsoft Windows [版本 5.2.3790]
(C) 版权所有 1985-2003 Microsoft Corp.C:\Documents and Settings\Administrator>netstat -aActive Connections Proto Local Address Foreign Address State
TCP kcrj:http kcrj:0 LISTENING
TCP kcrj:epmap kcrj:0 LISTENING
TCP kcrj:microsoft-ds kcrj:0 LISTENING
TCP kcrj:1025 kcrj:0 LISTENING
TCP kcrj:ms-sql-s kcrj:0 LISTENING
TCP kcrj:11111 kcrj:0 LISTENING
TCP kcrj:1301 kcrj:ms-sql-s ESTABLISHED
TCP kcrj:ms-sql-s kcrj:1301 ESTABLISHED
TCP kcrj:netbios-ssn kcrj:0 LISTENING
TCP kcrj:1224 KCRJSERVER:3389 ESTABLISHED
TCP kcrj:1284 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1302 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1303 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1304 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1305 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1306 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1307 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1308 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1309 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1310 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1311 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1312 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1313 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1314 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1315 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1316 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1317 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1318 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1319 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1320 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1321 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1322 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1323 KCRJSERVER:12005 TIME_WAIT
TCP kcrj:1324 KCRJSERVER:12005 TIME_WAIT5分种后客户端的;
Active Connections Proto Local Address Foreign Address State
TCP kcrj:http kcrj:0 LISTENING
TCP kcrj:epmap kcrj:0 LISTENING
TCP kcrj:microsoft-ds kcrj:0 LISTENING
TCP kcrj:1025 kcrj:0 LISTENING
TCP kcrj:ms-sql-s kcrj:0 LISTENING
TCP kcrj:11111 kcrj:0 LISTENING
TCP kcrj:1301 kcrj:ms-sql-s ESTABLISHED
TCP kcrj:ms-sql-s kcrj:1301 ESTABLISHED
TCP kcrj:netbios-ssn kcrj:0 LISTENING
TCP kcrj:1224 KCRJSERVER:3389 ESTABLISHED
TCP kcrj:netbios-ssn kcrj:0 LISTENING
TCP kcrj:netbios-ssn kcrj:0 LISTENING
UDP kcrj:microsoft-ds *:*
UDP kcrj:isakmp *:*
UDP kcrj:1030 *:*
UDP kcrj:1225 *:*
UDP kcrj:ms-sql-m *:*
UDP kcrj:4500 *:*
UDP kcrj:38037 *:*
UDP kcrj:ntp *:*
UDP kcrj:1230 *:*
UDP kcrj:ntp *:*
UDP kcrj:netbios-ns *:*
UDP kcrj:netbios-dgm *:*
UDP kcrj:2051 *:*
UDP kcrj:ntp *:*
UDP kcrj:netbios-ns *:*
UDP kcrj:netbios-dgm *:*
UDP kcrj:ntp *:*
UDP kcrj:netbios-ns *:*
UDP kcrj:netbios-dgm *:*
好象有一点眉头了,谢谢大家的支持,希望能够解决这一难题。somexing(张星星
服务器有没有设置SO_REUSEADDR 重用端口
netstat -a 看看,是否有许多 TIME_WAIT状态的连接没有释放占用了端口谢谢您的提示,请问服务器如何设置SO_REUSEADDR 重用端口??? Delphityro(菜鸟也是人) ( ) 信誉:100 2005-11-23 23:28:00 得分: 0
,发送的数据在OnReceive()不能接受了,在这个时间用远程登录可以登录到服务器,CPU也是4%左右
-----------------------------
问题很明显,肯定是端口用完了,telnet证明你的监听是有效的,但不是能accept了,就是分配不到端口了,关闭时你多半没有调用closesocket(),closesocket之前最好还调用一个shutdown(s, SD_BOTH)来温柔关闭。
我在OnAccept()中有检测的,如果accept失败,就写入一个文本,是否端口用完连OnAccept()函数都进不去了,关闭服务器程序她会不会又自动将端口释放出来呢?
比方20秒钟发送一个包
对方收到就返回一个包回来连续3次没收到返回包,就认定链路断了
就可以closesocket();
这样可以及时释放资源.
同时在客户端退出前告知服务器,并关闭该连接的SOCKET,并释放
很可能是socket资源没有释放掉,造成虚拟内存持续增加,当虚拟内存增加到一定数量是,新的socket资源申请就会失败。
在不能连接时,在资源管理器中看到内存是800M左右(一直都稳定的,系统是1G的内存)。: liuwei200000(太阳神) ( ) 信誉:100 2005-11-25 11:42:00 得分: 0
当客户端不能接收到你发送的数据时,应该关闭该SOCKET,并释放出来
同时在客户端退出前告知服务器,并关闭该连接的SOCKET,并释放
服务器是这样写,如果Send(s,s.GetLength)==SOCKET_ERROR 就关闭该SOCKET,所以说服务器是已经将SOCKET关闭了的。客户端Connect每次都是成功的,就不知道为什么服务器不返回数据,正常的话马上就返回数据了。
LZ查看一下出问题时核心内存中的分页和为分页内存是否过小服务器Accept不成功应该不是端口问题
LZ查看一下出问题时核心内存中的分页和为分页内存是否过小服务器Accept不成功应该不是端口问题
分页内存是否过小----------------------多少才是为过少?
若C和S已经连接,client关闭socket后会返回一个 空 给 server ,在server端作相应的关闭和释放处理.
若C和S已经连接,server关闭socket后,client端相应的socket会自动被释放掉啊.
我关闭连接一搬是 shutdown 然后 closesocket .