急救!!接收一定量的请求后,socket服务端不能再与客户端建立连接。(20分)

  • 主题发起人 panchenglin
  • 开始时间
P

panchenglin

Unregistered / Unconfirmed
GUEST, unregistred user!
我的通讯程序的服务端是多线程的,在接收一定量的客户端连接请求后不能再与客户端建立连接。需要重新启动服务端,甚至电脑。
从网上查了一下,有些朋友说可能是资源没有释放,socket连接没有释放,我看了一下程序,在线程结束前的finally中已经释放了资源:
closesocket(m_AcceptSocket);
m_AcceptSocket := INVALID_SOCKET;
但是问题依旧存在,请高手指点一下,不胜感激!
 
两边都加个shutdown(m_Socket,SD_BOTH);
试试看
 
to fhli,closesocket(m_AcceptSocket);不能彻底释放资源吗?
我从网上查了一下关于 shutdown():
int PASCAL FAR shutdown( SOCKET s, int how);
s:用于标识一个套接口的描述字。
how:标志,用于描述禁止哪些操作。注释:
shutdown()函数用于任何类型的套接口禁止接收、禁止发送或禁止收发。
如果how参数为0,则该套接口上的后续接收操作将被禁止。这对于低层协议无影响。对于TCP协议,TCP窗口不改变并接收前来的数据(但不确认)直至窗口满。对于UDP协议,接收并排队前来的数据。任何情况下都不会产生ICMP错误包。
若how为1,则禁止后续发送操作。对于TCP,将发送FIN。
若how为2,则同时禁止收和发。
请注意shutdown()函数并不关闭套接口,且套接口所占有的资源将被一直保持到closesocket()调用。
 
客户端和服务器端要定时握手,在服务器定时扫描,把超时没有握手的客户端kill掉
 
shutdown 是發一個 FIN 包給對方,告訴對方,我要關閉了
closesocket 是強制關閉,不通知對方。
一般shutdown 以後 sleep 一下。
而看你的代碼是用 closesocket(hAcceptSocket);
是用於 accept 的 socket 是可以不用 shutdown 的,而用於客戶通訊的 socket 要 shutdown
 
哦,我试一下
 
netstat -t 显示TCP协议的连接情况。
==========================================================
C:/Documents and Settings/Administrator>netstat -t
活动连接
协议 本地地址 外部地址 状态 卸载状态
TCP dqgjj-server-wi:1578 ABC:netbios-ssn ESTABLISHED 主栈中
TCP dqgjj-server-wi:3001 198.1.1.5:31748 CLOSE_WAIT 主栈中
TCP dqgjj-server-wi:3001 198.1.1.5:31787 CLOSE_WAIT 主栈中
TCP dqgjj-server-wi:3001 198.1.1.5:31804 CLOSE_WAIT 主栈中
TCP dqgjj-server-wi:3001 198.1.1.5:31824 CLOSE_WAIT 主栈中
TCP dqgjj-server-wi:3001 198.1.1.5:39268 CLOSE_WAIT 主栈中
TCP dqgjj-server-wi:ms-wbt-server YSICE:2141 ESTABLISHED
主栈中
TCP dqgjj-server-wi:ms-wbt-server MICROSOF-D6DCF5:2344 ESTABLISHED
主栈中
=================================================================
在程序中,监听端口为3001,socket等待连接队列的最大长度为5,如上所示:有5个连接还在等待关闭,并没有关闭。
是不是等待队列已经满了,并且不能释放这5个连接,所以拒绝接收新的请求, 大家分析一下是不是这样??????????????
 
netstat -a 显示所有socket,包括正在监听的
===========================================================================
C:/Documents and Settings/Administrator>netstat -a
Active Connections
Proto Local Address Foreign Address State
TCP dqgjj-server-wi:epmap dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:microsoft-ds dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:1026 dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:ms-sql-s dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:3001 dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:ms-wbt-server dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:1027 dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:netbios-ssn dqgjj-server-wi:0 LISTENING
TCP dqgjj-server-wi:1578 ABC:netbios-ssn ESTABLISHED
TCP dqgjj-server-wi:3001 198.1.1.5:31748 CLOSE_WAIT
TCP dqgjj-server-wi:3001 198.1.1.5:31787 CLOSE_WAIT
TCP dqgjj-server-wi:3001 198.1.1.5:31804 CLOSE_WAIT
TCP dqgjj-server-wi:3001 198.1.1.5:31824 CLOSE_WAIT
TCP dqgjj-server-wi:3001 198.1.1.5:39268 CLOSE_WAIT
TCP dqgjj-server-wi:ms-wbt-server YSICE:2141 ESTABLISHED
TCP dqgjj-server-wi:ms-wbt-server MICROSOF-D6DCF5:2344 ESTABLISHED
UDP dqgjj-server-wi:microsoft-ds *:*
UDP dqgjj-server-wi:isakmp *:*
UDP dqgjj-server-wi:ms-sql-m *:*
UDP dqgjj-server-wi:ipsec-msft *:*
UDP dqgjj-server-wi:ntp *:*
UDP dqgjj-server-wi:1025 *:*
UDP dqgjj-server-wi:ntp *:*
UDP dqgjj-server-wi:netbios-ns *:*
UDP dqgjj-server-wi:netbios-dgm *:*
===================================================================================
 
希望大家帮我分析一下原因,
(1)是不是Socket句柄用完导致的?
(2)等待队列中的连接为什么没有关闭?
 
服务端在接受客户端的很多次请求后才出现这种情况,也不容易判断是哪些请求的socket连接没有释放。请各位高手指点
 
问题还没有解决,时不时地出现这种情况,还没有办法跟踪。
 
最好吧问题描述清楚
是达到多少个链接才容易出现问题
出现的规律是什么样子的
 
在接收一定量的客户端连接请求后不能再与客户端建立连接
应该说明白点。是你自己的连接管理问题 还是Socket库的错误。而且不能客户端建立连接这话本身就有问题。请求连接的是客户端而不是服务端。服务端只是accept。请问你的accept返回了什么错误代码?
 
对不起大家了,这段时间太忙,没有时间来看自己的帖子。
to “不能没有你”朋友,谢谢您的建议
开始调用listen()时,设置的等待队列长度是5,服务死掉时,用netstat命令查看TCP连接数时,发现监听的端口有5个等待断开的TCP连接,后来把等待队列长度修改为60,服务的线程数也修改为60,把程序发给客户后,听说服务还是会死掉。我有个疑问:在windows server 2003下,调用listen()时,等待连接队列的长度最大可以设置为多少?
还有个情况必须得注意一下,有时客户端向服务端发起请求时非常频繁,隔几秒请求一次,服务端处理每个请求的时间多于1分钟,这时服务端很容易死掉,会有很多TCP连接等待断开但是没有断开,,这种频繁的请求是否类似于恶意攻击呢?
一个客户端这样频繁的请求势必会影响服务端处理其它客户端的请求。
to “地质灾害”朋友,谢谢您的建议
(1)accept()返回什么错误代码这个我会去看看
(2)我描述问题确实不准确,准确来说是,服务死掉后,服务端不能再接受客户端的请求。
 
你用任务管理器,到“进程”而,然后菜单"查看”-》选择列-》将句柄数钩上
然后查看你的EXE,句柄数是Windows资源,如果你程序里没有处理好以致不停的增长,那是程序问题,如果正常(句柄数一般在100->1000之间),那说明是其它问题,accept如果失败,用GetLastError查看一下是啥错误再说。
一般来说就是句柄(winsock handle, Windows Handle,etc...)没有正确关闭引起的。
 
to errorcode 朋友,我看了一下,句柄数为200多,应该是正常的。
“accept如果失败,用GetLastError查看一下是啥错误再说。”我再试试这个。
 
顶部