I'm implementing a very simple TIdCmdTCPServer
for receiving data from a cell phone application we also wrote. The cell application starts with a simple hello command, but the OnBeforeCommandHandler
comes with garbage.
AData
equals 'somerandomchars hello'
The random chars are non ASCII ones.
I'm using Delphi 2007 with the bundled Indy 10.1.5 components. I've tried this:
- Maybe my program was creating some corruption so I made a very simple
one with just a Form and a
TIdCmdTCPServer
. Same result. - Are the Delphi 2007 Indy components buggy? I switched to Delphi 10.3. Same problem.
- Is my computer somehow corrupting the communication? I ran the simple program in other Windows 10, both physical and virtual. Got the same problem.
- Maybe the cell application was sending wrong data. Tried using Putty to send the commands directly. No luck.
- Different port? Same
I've searched for this problem but found not a single page. In fact, they all state running a TIdCmdTCPServer
smoothly.
The most strange point is that after five or six commands, the data reads fine. On each event, the random chars are distinct from the previous one. After stepping through Indy code, I discovered that when it is about to read the very first time, it already has the random chars in the input buffer. Different "commands" need a different amount of cycles to begin reading without garbage. In the case of "hello", eight or nine times (not always the same).
What is causing this? I'm just starting the server with:
IdCmdTCPServer1.Active := True;
Does it need a separate thread? Indy's help doesn't say anything about that. No properties have been changed from the default ones.
Here is the code of the simple application:
unit test;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer,
IdCmdTCPServer, IdCommandHandlers, IdContext, IdServerIOHandler,
IdServerIOHandlerSocket, IdServerIOHandlerStack;
type
TForm1 = class(TForm)
cmdsMain: TIdCmdTCPServer;
ioshMain: TIdServerIOHandlerStack;
procedure FormShow(Sender: TObject);
procedure cmdsMainCommandHandlers0Command(ASender: TIdCommand);
procedure cmdsMainBeforeCommandHandler(ASender: TIdCmdTCPServer;
var AData: string; AContext: TIdContext);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.cmdsMainBeforeCommandHandler(ASender: TIdCmdTCPServer;
var AData: string; AContext: TIdContext);
begin
// here comes the garbagge
end;
procedure TForm1.cmdsMainCommandHandlers0Command(ASender: TIdCommand);
begin
//
end;
procedure TForm1.FormShow(Sender: TObject);
begin
cmdsMain.Active := True
end;
end.
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 299
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object cmdsMain: TIdCmdTCPServer
Bindings = <
item
IP = '0.0.0.0'
Port = 55
end>
DefaultPort = 55
IOHandler = ioshMain
CommandHandlers = <
item
CmdDelimiter = ' '
Command = 'hello'
Disconnect = False
Name = 'TIdCommandHandler0'
NormalReply.Code = '200'
ParamDelimiter = ' '
ParseParams = True
Tag = 0
OnCommand = cmdsMainCommandHandlers0Command
end>
ExceptionReply.Code = '500'
ExceptionReply.Text.Strings = (
'Unknown Internal Error')
Greeting.Code = '200'
Greeting.Text.Strings = (
'Welcome')
HelpReply.Code = '100'
HelpReply.Text.Strings = (
'Help follows')
MaxConnectionReply.Code = '300'
MaxConnectionReply.Text.Strings = (
'Too many connections. Try again later.')
ReplyTexts = <>
ReplyUnknownCommand.Code = '400'
ReplyUnknownCommand.Text.Strings = (
'Unknown Command')
OnBeforeCommandHandler = cmdsMainBeforeCommandHandler
Left = 312
Top = 152
end
object ioshMain: TIdServerIOHandlerStack
Left = 376
Top = 168
end
end
UPDATE: We modified the cell app to just send the commands to an echo server: tcpbin.com. The echo was received fine. We emulated the cell to the same server using Putty just to ensure that it was generating any garbage. In both, it ran fine.
CodePudding user response:
The fact that you can reproduce the issue across multiple Indy versions and multiple server machines tells me the problem is likely not with the server at all, but with the client. For instance, if you are using Putty in telnet mode instead of raw mode.