2013-05-05 62 views
0

我在做什么: 我的服务器通过上下文列表发送数据,并在它锁定到特定客户端后发送该客户端数据,并且它期望我们在此连接中处理的答复计时器。 我明白,使用线程将是一个更好的方法来做到这一点,但这是我一起去的。Delphi Indy 10断开连接问题

这里是我的问题: 我请求得到连接信息,它工作正常,插座写入线GetString的数据1 throught 8 但是当我写“你好”它不只是断开客户端的数据作出反应。

任何帮助将不胜感激,试图找出这个为期2天左右。 在此先感谢!

这里是我的代码:

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; 
+0

您正在使用'WriteLn()'作为''Get Connection Info''回复,但正在使用'Write()'作为其他回复。服务器是否期望在每个回复中都有换行符? – 2013-05-06 03:44:13

回答

0

雷米谢谢你的快速回复,我的朋友和我在这个项目上发布了这个问题之后一起,不久合作,我们双方很快确定有我们其中真问题我们已经修复了它!

对于任何固定的代码谁需要它:

客户端:(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; 

我希望这个例子可以帮助别人的人是有同时使用印插座随机断开的问题,哈哈它通常是程序员故障,而不是他或她选择使用的组件集。

我很抱歉,如果这个示例代码是不可读的,这是在这个网站我第一次发贴,我敢肯定,在以后的文章中我会努力正确地格式化我的意见等...等...

另外我想为任何试图在客户端接收这样的数据的人添加,最好是创建自己的后台工作线程以侦听来自TidTCPserver套接字的传入连接。我知道这个计时器是不好的编程习惯,事实上我和我的朋友很快就会把它切换到一个单独的线程。

雷米再次我想你的快速回复!非常感谢先生。

+1

代码格式可能会更好;-) – mjn 2013-05-06 19:03:34

+0

我知道这个评论是LATE哈哈,但是是的代码是crud只是为了解决这个问题,我们的实际代码是更好,我们使用线程保存队列列表和各种东西在我们的完成品 :) – TheBitmasterXor 2014-09-28 18:04:13