DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: liangjiping168
今日帖子: 16
在线用户: 12
导航: 论坛 -> 网络通讯 斑竹:liumazi,sephil  
作者:
男 iamcws (你健康我快乐) ★☆☆☆☆ -
普通会员
2015/11/27 14:01:51
标题:
IdTCPServer,网络出现异常后,客户端再次连接到服务端后,连接数会不断开增加,有何解决办法? 浏览:2199
加入我的收藏
楼主: 服务端用IdTCPServer,由于客户端和服务端之间的网络经常会出现异常,客户端再次连接到服务端后,IdTCPServer的连接数会不断开增加,直到到达IdTCPServer的最大连接数后,服务端程序就停止工作了,请问各位老师有何解决办法?这个问题一直困扰着我,还望老师们多多指点,谢谢!
----------------------------------------------
不要等到孤独寂寞时才想起朋友,不要等到穷困潦倒时才想起发奋,不要等到疾病缠身时才想起健康。。。
作者:
男 z5104242 (行者) ▲▲▲▲▲ -
普通会员
2015/11/27 15:26:57
1楼: 另外开一个线程,扫描清除
----------------------------------------------
-
作者:
男 iamcws (你健康我快乐) ★☆☆☆☆ -
普通会员
2015/11/27 18:47:06
2楼: 如何扫描?虽然网络异常,但AThread.Connection.Connected可能仍然为true呀,希望老师能给出具体代码,谢谢!
----------------------------------------------
不要等到孤独寂寞时才想起朋友,不要等到穷困潦倒时才想起发奋,不要等到疾病缠身时才想起健康。。。
作者:
男 421 (421) ★☆☆☆☆ -
盒子活跃会员
2015/11/28 18:58:41
3楼: 设置KEEPALIVE
----------------------------------------------
-
作者:
男 frank_killer (图坦卡蒙) ▲▲▲▲△ -
普通会员
2015/11/28 21:37:23
4楼: 加上心跳包,心跳包超时就清理掉那个socket,主意释放掉线程中创建的对象,否则容易内存泄漏
----------------------------------------------
迷茫的delphi草脚
作者:
男 qiuyan81 (苦恋树) ★☆☆☆☆ -
普通会员
2015/11/29 1:47:37
5楼: 简单点的服务器就用KEEPALIVE这个TCP自带的机制。

考虑高性能服务器还是得客户端发送心跳数据,
服务端用时间轮来确定客户端状态。。。
----------------------------------------------
作者:
男 iamcws (你健康我快乐) ★☆☆☆☆ -
普通会员
2015/11/30 18:44:29
6楼: type
  TTCP_KeepAlive = packed record
    OnOff: Cardinal;
    KeepAliveTime: Cardinal;
    KeepAliveInterval: Cardinal;
  end;

procedure TGPRSForm.IdTCPServerConnect(AThread: TIdPeerThread);
Var
  strIP, strPort : String;
  tcpInKeepAlive, tcpOutKeepAlive : TTCP_KeepAlive;
  iOpt : Integer;
begin
  try
    strIP := AThread.Connection.Socket.Binding.PeerIP;
    strPort := IntToStr(AThread.Connection.Socket.Binding.PeerPort);
    if bShowMsg then AddMsgToRichEdit('终端(IP:' + strIP + ',Port:' + strPort + ')已经连接!');
    //if bStop then CloseGPRSSocket(AThread);
    iOpt := 1;
    if SetSockOpt(AThread.Connection.Socket.Binding.Handle, SOL_SOCKET, SO_KEEPALIVE, @iOpt, SizeOf(iOpt)) = 0 then
    begin
      tcpInKeepAlive.OnOff := 1;
      tcpInKeepAlive.KeepAliveTime := 360000; //TCP连接6分钟没有数据就开始发送心跳包,有数据传递的时候不发送心跳包
      tcpInKeepAlive.KeepAliveInterval := 5000;  //每隔5秒发送一个心跳包,发5次(系统默认值)
      if WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @tcpInKeepAlive,
          SizeOf(TTCP_KeepAlive), @tcpOutKeepAlive,
          SizeOf(TTCP_KeepAlive), @iOpt, 0, nil) = SOCKET_ERROR then
        AddMsgToRichEdit('IP:' + strIP + ', Port: ' + strPort + ' --- WSAIoctl KeepAlive Error!');
    end;
  except
    on E: Exception do
    begin
      AddMsgToRichEdit('Connect : ' + E.Message);
      Exit;
    end;
  end;
end;

从上面的代码可以看出,我在IdTCPServer的Connect事件中是加了心跳包的,但连接数还是会不断增加,是不是在其他地方还需要处理?如果处理,希望老师发段你们曾经写的一段代码指导我一下,万分感谢!
----------------------------------------------
不要等到孤独寂寞时才想起朋友,不要等到穷困潦倒时才想起发奋,不要等到疾病缠身时才想起健康。。。
作者:
男 iamcws (你健康我快乐) ★☆☆☆☆ -
普通会员
2015/12/2 8:30:34
7楼: procedure TGPRSForm.IdTCPServerException(AThread: TIdPeerThread; AException: Exception);
begin
  try
    if not AThread.Terminated then
    begin
      AThread.Stop;
      AThread.Terminate;
    end;
    if AThread.Connection.Connected then
      AThread.Connection.Disconnect;
  except
  end;
end;
在Exception事件中也做了处理,为何连接数还是不断增加,没有任何效果,有没有哪位老师遇到过类似的问题,如果解决?请老师们指教!谢谢
----------------------------------------------
不要等到孤独寂寞时才想起朋友,不要等到穷困潦倒时才想起发奋,不要等到疾病缠身时才想起健康。。。
作者:
男 iamcws (你健康我快乐) ★☆☆☆☆ -
普通会员
2015/12/2 8:33:42
8楼: 客户端不是自己写的程序,客户端是GPRS终端设备。
procedure TGPRSForm.IdTCPServerConnect(AThread: TIdPeerThread);
Var
  strIP, strPort : String;
  tcpInKeepAlive, tcpOutKeepAlive : TTCP_KeepAlive;
  iOpt : Integer;
begin
  try
    strIP := AThread.Connection.Socket.Binding.PeerIP;
    strPort := IntToStr(AThread.Connection.Socket.Binding.PeerPort);
    if bShowMsg then AddMsgToRichEdit('终端(IP:' + strIP + ',Port:' + strPort + ')已经连接!');
    //if bStop then CloseGPRSSocket(AThread);
    iOpt := 1;
    if SetSockOpt(AThread.Connection.Socket.Binding.Handle, SOL_SOCKET, SO_KEEPALIVE, @iOpt, SizeOf(iOpt)) <> 0 then AddMsgToRichEdit('SetSockOpt KeepAlive Error!');
    tcpInKeepAlive.OnOff := 1;
    tcpInKeepAlive.KeepAliveTime := 360000; //TCP连接6分钟没有数据就开始发送心跳包,有数据传递的时候不发送心跳包
    tcpInKeepAlive.KeepAliveInterval := 1;  //每隔1秒发送一个心跳包,发5次(系统默认值)
    if WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @tcpInKeepAlive,
          SizeOf(TTCP_KeepAlive), @tcpOutKeepAlive, SizeOf(TTCP_KeepAlive), @iOpt, 0, nil) = SOCKET_ERROR then
      AddMsgToRichEdit('IP:' + strIP + ', Port: ' + strPort + ' --- WSAIoctl KeepAlive Error!');
  except
  end;
end;
----------------------------------------------
不要等到孤独寂寞时才想起朋友,不要等到穷困潦倒时才想起发奋,不要等到疾病缠身时才想起健康。。。
作者:
男 glings (glings) ★☆☆☆☆ -
普通会员
2015/12/3 10:19:52
9楼: 客户端并不一定是用IDTCP做的,所以在服务端写心跳包,也没有用的,
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行70.3125毫秒 RSS