ServerSocket的一个问题,请进!!!!(50分)

  • 主题发起人 主题发起人 gsw798
  • 开始时间 开始时间
G

gsw798

Unregistered / Unconfirmed
GUEST, unregistred user!
用ServerSocket来侦听客户端,
但发现它在运行一两天后就不响应了。
问题可能出在哪里,如何解决?
(先出50分,不够再加。QQ:27191895)
 
非常关注。
我也遇到此问题,无法解决,查阅了大量资料,
据说是TCP/IP交换了大量数据、反复加载和卸载socket造成的“内存渗漏”,
大概这个问题是无解了,只能等Bill Gates在Windows 3000中解决了。
 
贴出代码可能有利于诊断。
 
我开发的项目,也曾碰到不响应客户连接的情况,因为服务器端采用多线程编程,
所以用到了很多同步机制,不知道gsw798主线程中是否也用到了同步,因为如果考
虑不周,很可能使主线程阻塞,这是导致不响应的主要原因。
 
偶碰到过,就是已经建立连接的client-server,若网线你拔下来,若双方不进行
发送数据的化,那么它们处于虚假连接状态,但server仍然认为是好的连接。这个偶
还没有想到解决方法,只有你进行发送数据后,才会测到连接失败(通过发送失败)。
若是可以的化,你可以定期发送测试数据是否在线的测试数据(1/0就可以了)。
当然,这建立在你用的socket传输数据是完全自己处理的,而不是用SOCKET作MIDAS
另外,你可以试试ICS控件,据说它功能非常完善,可能能解决这个问题。SOCKET
API 也有桢听功能;不止能解决否?
另外,干吗不用的时候建立连接,用完断开;有必要连了两三天不传输数据么?


 
To Jakie_Sun:
-因为服务器端采用多线程编程,所以用到了很多同步机制,
-不知道gsw798主线程中是否也用到了同步,因为如果考虑不周,
-很可能使主线程阻塞,这是导致不响应的主要原因。
是的,我是用了多线程(10个,在属性里面设置的),ServerType:=stNonBlocking;
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode:=0;
end;
出现错误的事件处理。

To jinchi:
现在不可能换控件的,程序都这样定下来,要改动比较麻烦。
 所以现在还得用这个控件,以后是不会再用ServerSocket了。
 就种情况难道没有办法来解决吗?

我的想法是这样的(我没有试过),先和大家讨论一下:
  在这个程序上另加一个ClientSocket控件,用它来和ServerSocket联接,
  当联接失败,就说明ServerSocket出了问题,然后就把这个ServerSocket Free掉,
  再生成一个ServerSocket,设置属性和原来的一样,启动这个新生成的ServerSocket。
  (还有一个问题是当ServerSocket出问题时,ClientSocket是不是也一样会停止响应
  的问题?)





 
 今天程序又出问题了(运行第三天)。
 从事件记录来看,联接过程没有出现错误联接现象。
 但ServerSocket还是停止了响应,我用了DisConnect方法后又Connect,还是不行。
 只好重新启动程序。事件记录看,共不超过20个联接。
 

 
[:(]无能为力
比较赞成guorm的观点
 
一两天没事,时间长了就当掉,程序本身应该不会有问题,可能是Socket buffer溢出了吧!
还是哪里的资源累积没有释放造成的!
------------------
具体的我也不清楚!帮你提前!
 
To gsw798
ServerSocket不响应,我觉得很可能是主程序在等同步对象的原因,
因为不知你的实现方式,因此仅是猜测,我前一段时间也在做类似的
开发,我也是用异步Socket,并且对每一个连接,用两个线程,分别负
则收发,做了很多同步,也出现过不响应的情况,发现是因为主线程执
行了WaitforSingleObject操作,处于等待(可设超时),无法响应OnAccept
/OnConnect等事件,后来我将所有类似的操作都以线程执行,比如在OnDisconnect
事件中我创建线程释放和该Socket相关的资源,问题得到解决,所以你要好好
检查程序,看看有没有死锁的可能。
另,如果网线被拔了,有两种情况,拔掉和服务器上的网线,如果是win2k,系统
可以立刻作出反应,ServerSocket上立刻发生OnError/OnDisconnect事件,具体是
那个事件,我已记不清了,如果是远端客户,服务器并不知道该连接已经断开,需
要做些操作来检测,我的服务器上有一个线程,定时发ICMP包,如果Ping不通,则
释放该Socket资源。
一般在编写这种程序时,对应用程序定义的包,都有一个空操作的包,它没有具体
的业务意义,仅仅是判断当前Socket连接是否可用,对方接受到这种包,也是什么也
不处理,丢弃到,我觉得这很有意义。
Socket.Close会出发OnDisconnect事件,要确保OnDisconnect事件只被触发一次,
 
呵呵,对RECV函数进行超时控制,超过一段时间没有收到数据就关闭这个套接字,强迫
用户在次连接
 
To Jakie_Sun:
我对ServerSocket线程的编写不太熟悉,你能否给我发个例程?
gsw798@163.net 
 
对不起,我对ServerSocket线程的编写不太熟悉,也没写过类似的程序。
 
TO 张无忌:
  给个解决办法(最好给个例子),谢谢!!
 
我看到资料上说,可以用线程(TServerClientThread),
 但是当有一线程存在时,ServerSocket不能Close,
 如何才能Close呢?
 
>>如何才能Close
好像要在Close之前Free所有的Thread
 
多人接受答案了。
 
后退
顶部