使用TClientSocket时,当服务端断开时报10053的错误,而TClientSocket仍然处于连接状态 ( 积分: 200 )

  • 主题发起人 主题发起人 joechan
  • 开始时间 开始时间
J

joechan

Unregistered / Unconfirmed
GUEST, unregistred user!
本人开发门锁软件,最近跟全球最大的酒店管理软件Fidelio做远程调试。我方是客户端,它是服务端。与它连接及通讯都没有问题,但当它的Socket退出时我方总是报10053错误,而且我方的ClientSocket仍然处于连接状态。
注:
1.它断开之前会先发一个命令过来通知我,然后不管我是否回复就马上退出。
2.我自己做了个模拟它的服务端,在局内网中测试过没问题。
时间很赶,麻烦懂得的人给小弟一点帮助。
 
本人开发门锁软件,最近跟全球最大的酒店管理软件Fidelio做远程调试。我方是客户端,它是服务端。与它连接及通讯都没有问题,但当它的Socket退出时我方总是报10053错误,而且我方的ClientSocket仍然处于连接状态。
注:
1.它断开之前会先发一个命令过来通知我,然后不管我是否回复就马上退出。
2.我自己做了个模拟它的服务端,在局内网中测试过没问题。
时间很赶,麻烦懂得的人给小弟一点帮助。
 
要不你看看这个???
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2289566
TClient/ServerSocket下的通讯程序,客户端无故自动关闭(简直就是一个自杀文件!)

还有这些个
可以考虑用TCP自己的保活定时器,他的作用是每隔一段时间检查一下连接是否正常,如果不正常则报告给应用层。
用下面的方法试试,理论上应该是对的,偶没有实际测试先
uses WinSock;

在TCPServer的OnConnection事件里加上如下的片段:
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
type
TCP_KeepAlive = record
OnOff: Cardinal;
KeepAliveTime: Cardinal;
KeepAliveInterval: Cardinal
end;
var
Val: TCP_KeepAlive;
Arg: Integer;
begin
Val.OnOff:=1;
Val.KeepAliveTime:=xxx;
Val.KeepAliveInterval:=xxx;
Arg:=Integer(@Val);
ioctlsocket(AThread.Connection.Socket.Binding.Handle,
$80000000 or $18000000 or 4, Arg);
end;

TCP_KeepAlive里的参数的意义是显而易见的,就不多说了。
然后连接将自动按指定间隔测试是否正常,作为应用程序可以在TCPServer的OnException里守着就行了。


来自:LeeChange, 时间:2004-6-9 11:00:30, ID:2653438
心里没底,怕WinSock 1不支持,你最好还是用类似下面的片段吧。
uses WinSock2;

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
type
TCP_KeepAlive = record
OnOff: Cardinal;
KeepAliveTime: Cardinal;
KeepAliveInterval: Cardinal
end;
var
Val: TCP_KeepAlive;
Ret: DWord;
begin
Val.OnOff:=1;
Val.KeepAliveTime:=xxx;
Val.KeepAliveInterval:=xxx;
WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @Val, SizeOf(Val), nil, 0, @Ret, nil, nil)
end;

sorry,我错了,刚才测试第二种方法没有给参数赋值,现在赋值正确了,6000=6秒,拔掉网线6秒立即报告断开。成了了。
 
To app2001:
谢谢你的帮忙,但你可能误会了我得意思。客户端是我这边开发的,但服务端那边是Fidelio的接口端,并不是我开发的,我也不能修改它。现在最大的问题是对方(Fidelio)断开时我方就马上报10053错误,而且出现异常之后,我的客户端(TClientSocket)并没有断开(我判断此时的Socket.Active仍为True,而事实上对方已退出程序了),现在我参照你给的地址http://www.delphibbs.com/delphibbs/dispq.asp?lid=2289566
在TClientSocket的OnError事件中加入代码:
ErrorCode := 0; //屏蔽Socket的异常
case ErrorEvent of
eeGeneral:
eeSend:
eeReceive:
eeConnect:
Socket.Close;
eeDisconnect:
Socket.Close;
eeAccept:
eeLookup:
end;
不知道行不行,我明天试一下。在此,请大家也过来讨论一下吧,我给老板摧得很急,分数不够我会加的。
 
10053 Connection is aborted due to timeout or other failure.
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2405933
标题: Asynchronous socket error 10053?

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1357442
标题: 关于serversocket的10053错误 (100分)

http://www.delphibbs.com/delphibbs/dispq.asp?lid=2106868
标题: serversocket断开clientsocket报错??? (50分)
 
to chenybin:
你列出的地址:http://www.delphibbs.com/delphibbs/dispq.asp?lid=2106868
里面的“发送端成功发送了数据包,但接收端没有接收就关闭了socket退出,这时发送端就会触发这个错误。”对我很有启发,因为Fidelio断开之前会先发一个命令过来通知我,然后不管我是否收到就马上退出。只是现在我还没有落实到解决方法,明天我再跟Fidelio连接试一下。
但话又说回来,我自己做的模拟服务端在局内网跟我的客户端连是没问题的,而且我的服务端断开之前也是先发一个命令过来,并且不等回复就马上退出了。
 
看能不能用抓包的工具看看是不是发了什么不对的数据过来
 
to chenybin:
不好意思,这几天忙呀,没有看贴子。
实际上,在TClientSocket的OnError事件中加入代码Socket.Close已能基本解决问题(注意此时会触发OnDisconnect事件),但不知道还有没有隐患。
这几天我试过使用TTcpClient控件,感觉没有出现这种错误。到底是什么原因?说实话,我本人比较喜欢使用TClientSocket,它的功能比较强。虽然TTcpClient比较容易使用,但就是太简单了,限制比较多。而且我不明白为什么Delphi7中没有把TClientSocket作为默认的控件,而用TTcpClient代替了,是不是TClientSocket有Bug?请各位指教指教。
 
多人接受答案了。
 
后退
顶部