简体   繁体   English

Delphi Indy 10断开连接问题

[英]Delphi Indy 10 Disconnection issue

What i am doing: My server sends data by going through the context list and after it locks on to the specific client it sends that client data, and it expects a reply which we handle in this connection timer. 我正在做什么:我的服务器通过上下文列表发送数据,并锁定到特定的客户端后,它发送该客户端数据,并期望我们在此连接计时器中处理答复。 I understand that using a thread would be a better way to do this but this is what i went with. 我知道使用线程是执行此操作的更好方法,但这就是我所追求的。

Here is my problem: I request get connection info and it works fine, the socket writes line getstring data 1 throught 8 but when i write 'Hello' it does not respond with any data it just disconnects the client. 这是我的问题:我请求获取连接信息,并且工作正常,套接字将行getstring数据写入1至8,但是当我写“ Hello”时,它不响应任何数据,只会断开客户端连接。

Any help would be greatly appreciated been trying to figure this out for 2 days or so. 试图解决2天左右的任何帮助将不胜感激。 Thanks in advance! 提前致谢!

Here is my code: 这是我的代码:

procedure TForm1.CommandTimerTimer(Sender: TObject);
var
sl:Tstringlist;
Command: String;
begin
  if clientsocket.IOHandler.InputBufferIsEmpty then
  begin
    clientsocket.IOHandler.CheckForDataOnSource(10);
    if clientsocket.IOHandler.InputBufferIsEmpty then Exit;
  end;
  Command := clientsocket.IOHandler.ReadLn();
  sl:= Tstringlist.Create;
  sl.Delimiter:= '|';
  sl.StrictDelimiter:=true;
  sl.DelimitedText:= Command;
  if sl[0] = 'did i get data' then
  begin
   showmessage('Yea I got Data');
  end;


if sl[0] = 'BroadCasted Message' then
begin
Clientsocket.IOHandler.write('data');
showmessage(sl[1]); // This is data sent from my server to this client, in order to manage the data I have created a Tstringlist and delimited it out by '|'. 
end;
if sl[0] = 'hello' then
begin
  clientsocket.IOHandler.write('data');
end;
if sl[0] = 'Get Connection Info' then
begin
// This part
clientsocket.IOHandler.writeln('Newconnection' + '|' + 'string data 1'  + '|' + 'string data 2' + '|' + 'string data 3' + '|'+ 'string data 4'+'|' + 'string data 5'+'|'+'string data 6'+'|'+'string data 7'+'|'+'string data 8');
end;

if sl[0] = 'Reconnect' then
begin
commandtimer.Enabled:=false;
Connectiontimer.Enabled:=true; // This is a timer that constantly checks and keeps the TidTCPclientsocket connected with my server as this is a Reverse connection Protocol.
Exit;
end;
commandtimer.enabled:=true;
end;

Remy Thank you for the quick reply, My friend and I are working on this project together and shortly after posting this question we both quickly determined the true issue we where having and we have Fixed it! Remy感谢您的快速答复,我和我的朋友正在共同努力进行这个项目,发布此问题后不久,我们俩都迅速确定了我们所遇到的真正问题,并已修复它!

The Fixed code for anyone who needs it: 需要的人的固定代码:

Client Side:(Tidtcpclient) 客户端:(Tidtcpclient)

     procedure TForm1.CommandTimerTimer(Sender: TObject);
        var
        sl:Tstringlist;
        Command: String;
        begin
            if clientsocket.IOHandler.InputBufferIsEmpty then
        begin
            clientsocket.IOHandler.CheckForDataOnSource(10);
            if clientsocket.IOHandler.InputBufferIsEmpty then Exit;
          end;
          Command := clientsocket.IOHandler.ReadLn();
          sl:= Tstringlist.Create;
          sl.Delimiter:= '|';
          sl.StrictDelimiter:=true;
          sl.DelimitedText:= Command;
          if sl[0] = 'Get Connection Info' then
          begin
      clientsocket.IOHandler.writeln('String Data 1' + '|' + 'String Data 2'+ '|' + 'String     Data 3'+ '|' + 'String Data 4' + '|'+ 'String Data 5'+'|' + 'String Data 6'+'|'+'String Data 7'+'|'+'String Data 8'+'|'+'String Data 9' + '|' + 'String Data 10' + '|' + 'String Data 11');
end
else
if sl[0] = 'hello' then
begin
showmessage('I got Hello');
clientsocket.IOHandler.writeln('Some Data');
end;
if sl[0] = 'PING!' then
begin
clientsocket.IOHandler.WriteLn('PINGBACK!');
end;

commandtimer.enabled:=true;
end;

Server Side: (TidTCPserver) OnExecute Event Procedure

procedure TForm1.ServersocketExecute(AContext: TIdContext);
Var
sl:Tstringlist;
listitem:Tlistitem;  // This is for a Tlistview where we are adding connection information
Data:String;
Begin
data:= acontext.connection.iohandler.readln(); 
sl:= Tstringlist.create;
sl.delimiter:= '|';
sl.delimitedtext:= data;

    If sl[0] = 'String Data 1' then
begin
listitem:= listview1.items.add;
listitem.caption:= acontext.binding.peerip;
listitem.subitems.add(sl[2]);
listitem.subitems.add(sl[3]);
listitem.subitems.add(sl[4]);
listitem.subitems.add(sl[5]);
listitem.subitems.add(sl[6]);
listitem.subitems.add(sl[7]);
listitem.subitems.add(sl[8]);
listitem.subitems.add(sl[9]);
listitem.subitems.add(sl[10]);

after we add items to the listview component we then go into our own ping method.

Allow me to show everyone what the problem was: 

we recived commands based on the FIRST string received by the clientsocket IE:

If sl[0] = 'Command sent by Client' then
begin

end;

and we kept it going on and on and on IE: 

If sl[0] = 'Command sent by Client' then
begin

end;
If sl[0] = 'Command sent by Client' then
begin

end;

The problem with this is that we cannot allow this code to run on and on like this otherwise the socket hangs and disconnects.

The fix was Simple   Example:

If sl[0] = 'Command sent by Client' then
begin
// Do what we have to do in this instance of receiving a Command and then Exit the sub / Procedure.
exit;
end;

If sl[0] = 'Command sent by Client' then
begin
// do what we got to do in here
Exit; // DON'T forget the exit statement or code runs on and will hang the socket. 
end;

I hope this Example helps anyone else whom is having issues with random disconnections while using indy sockets, lol its usually the programmers fault not the component set he or she is choosing to use. 我希望这个示例可以帮助使用indy套接字时出现随机断开连接问题的其他任何人,这通常是程序员认为不是他或她选择使用的组件集的错误。

I'm sorry if this Example code is unreadable this is my first time posting on this site and I'm sure that in future posts I will strive to properly format my comments Ect... Ect... 很抱歉,如果此示例代码不可读,这是我第一次在该网站上发布文章,并且我相信在以后的文章中,我将努力正确地设置我的评论格式等等。

Also I would like to add for anyone whom is trying to receive data like this on the client side that it would be best best to create your own background worker thread to listen for incoming connections from a TidTCPserver socket. 另外,我想向尝试在客户端接收此类数据的任何人添加一个最好的方法,那就是最好创建您自己的后台工作线程,以侦听来自TidTCPserver套接字的传入连接。 I understand that the timer is bad programming practice and in fact my friend and I will switch it over to a separate thread soon. 我知道计时器是不好的编程习惯,实际上我的朋友和我会尽快将其切换到单独的线程。

Remy once again I think you for your quick reply! 雷米,我想再次感谢您的快速回复! Much appreciated sir. 非常感谢先生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM