 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Philip Colley Guest
|
Posted: Fri Feb 17, 2006 9:03 pm Post subject: New to TIdTCPClient and struggling. |
|
|
Hi
This is the first time I've ever used Indy(10) and am struggling so could
anyone help? Using BDS2006
I have a samll test app that has the TIdTCPClient that should connect to
"Tibbo" server component that allows comunications with an Alarm system via
tcp. I have successfully written a program to communicate using the same
protocol via a RS232 connection but now I want to switch to the Tcp
connection which should meen just changing the method of communications,
commands and format remain as previous.
I have proved the connection and commands work over the tcp by using
Hyperterminal.
The TIdTCPClient appears to connect, some manger software supplied by
"Tibbo" shows that I have connected and the device LED shows packets
arriving, but I cannot get the server to respond. For security reasons the
Alarm System will not respond until it receives a valid login which takes
the form of <STX> <command>(params)<CR>. I've used the same format as the
serial version and sent by calling
"IdTCPClient1.IOHandler.WriteLn(^C+LI1234+^M)" and various other forms of
the Write method. I've got basic event sets up to register if "OnWork",
"OnWorkBegin" and "OnWorkEnd" but they are never called, If I do a
IOHandler.ReadLn after the write the program just sits non responsive
waiting.
I was hopping that this would operate the same as the Comport version where
the component automatically notifies me when data arrives. To me this points
to the login not being formatted correctly so the server will not start
sending.
Any one have any suggestions?
Thanks
Phil |
|
| Back to top |
|
 |
Don Guest
|
Posted: Sat Feb 18, 2006 1:03 am Post subject: Re: New to TIdTCPClient and struggling. |
|
|
| Quote: | For security reasons the Alarm System will not respond until it receives a
valid login which takes the form of <STX> <command>(params)<CR>. I've used
the same format as the serial version and sent by calling
"IdTCPClient1.IOHandler.WriteLn(^C+LI1234+^M)" and various other forms of
the Write method.
|
If the data is supposed to be terminated by CR (#13), then the WriteLn
method is not the one to use. It appends an EOL characater sequence (both
CR and LF characters).
I dont know what type L1234 is, so I am assuming L1234 is a string value.
Try using:
IdTCPClient1.IOHandler.Write(#3); // CtrlC
IdTCPClient1.IOHandler.Write(L1234); // whatever...
IdTCPClient1.IOHandler.Write(#13); // CtrlM
| Quote: | I've got basic event sets up to register if "OnWork", "OnWorkBegin" and
"OnWorkEnd" but they are never called, If I do a IOHandler.ReadLn after
the write the program just sits non responsive waiting.
|
If the response data is not delimited with CR+LF characters, the unadorned
ReadLn method is not the one to call. If the response is delimited with CR
only (no LF), you need to use the overloaded method in IOHandler where you
can specify the terminator:
sResponse := IdTCPClient1.IOHandler.ReadLn(CR);
OnWork should get fired during the write operation(s). OnWork is not going
to be fired during a read operation until something is received from the
remote host and gets handled in the internal buffer for the client.
OnWorkBegin and OnWorkEnd are not going to be fired unless you wrap the read
and write operations with BeginWork and EndWork calls. TIdTCPClient has no
idea what type of protocol you're using, so it cannot discern where these
calls are needed.
| Quote: | I was hopping that this would operate the same as the Comport version
where the component automatically notifies me when data arrives. To me
this points to the login not being formatted correctly so the server will
not start sending.
|
Indy is a blocking socket library. The above describes behavior like that
for asynchronous sockets. But that doesn't really appear to be the protocol
you're using; you're writing a command and reading a response in the
example. Asynchronous notifications would only complicate that simple
scenario.
hth... |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Sat Feb 18, 2006 5:03 am Post subject: Re: New to TIdTCPClient and struggling. |
|
|
"Philip Colley" <pjcolley (AT) globalnet (DOT) co.uk> wrote in message
news:43f62f47$1 (AT) newsgroups (DOT) borland.com...
| Quote: | The TIdTCPClient appears to connect, some manger software supplied by
"Tibbo" shows that I have connected and the device LED shows packets
arriving, but I cannot get the server to respond.
|
Please show your actual code. You are likely using the socket incorrectly.
| Quote: | For security reasons the Alarm System will not respond until it receives a
valid login which takes the form of <STX> <command>(params)<CR>.
|
For example:
procedure WriteCommand(const ACmd, AParams: String);
begin
//...
IdTCPClient1.IOHandler.Write(#2+ACmd+AParams+#13);
//...
end;
Or:
procedure WriteCommand(const ACmd, AParams: String);
var
LBuf: TIdBytes;
begin
//...
SetLength(LBuf, 1+Length(ACmd)+Length(AParams)+1);
LBuf[0] := $02;
CopyTIdString(ACmd, LBuf, 1);
CopyTIdString(AParams, LBuf, 1+Length(ACmd));
LBuf[Length(LBuf)-1] := $0D;
IdTCPClient1.IOHandler.Write(LBuf);
//...
end;
Or:
procedure WriteCommand(const ACmd, AParams: String);
begin
//...
with IdTCPClient1.IOHandler do
begin
Write(Byte($02));
Write(ACmd);
Write(AParams);
Write(Byte($0D));
end;
//...
end;
| Quote: | I've used the same format as the serial version and sent by calling
"IdTCPClient1.IOHandler.WriteLn(^C+LI1234+^M)"
|
WriteLn() appends the data with a CRLF at the end. As such, you are writing
too many characters to the connection.
| Quote: | and various other forms of the Write method.
|
Please show your actual code.
| Quote: | I've got basic event sets up to register if "OnWork", "OnWorkBegin" and
"OnWorkEnd" but they are never called
|
The OnWork and OnWorkEnd events are only triggered when the OnWorkBegin
event has been triggered first. OnWorkBegin is only triggered for
operations that require multiple reads/writes internally, such as
reading/writing streams. Reading/writing individual values do no trigger
the events.
| Quote: | If I do a IOHandler.ReadLn after the write the program just sits
non responsive waiting.
|
By default, ReadLn() expects the data to be terminated by LF, which is not
the case in this situation. The data is terminated by CR instead. Are you
specifying CR as the ATerminator for ReadLn()?
| Quote: | I was hopping that this would operate the same as the Comport version
where the component automatically notifies me when data arrives.
|
Indy is not an asynchronous library. Operations block the calling thread
until they complete (or an error occurs). In order to process incoming
packets asynchronously using Indy, you will have to move the reading into a
timer or worker thread (I would suggest a thread). Otheerwise, swwitch to
an asynchronous library, such as ICS (http://www.overbyte.be).
| Quote: | To me this points to the login not being formatted correctly
|
That is hard to say without seeing your actual code.
Gambit |
|
| Back to top |
|
 |
Philip Colley Guest
|
Posted: Sat Feb 18, 2006 10:03 am Post subject: Re: New to TIdTCPClient and struggling. |
|
|
Thanks for the help guys.
I've switched to the ICS components as advised and with the help of one of
the demo apps have things working.
Phil
"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote in message
news:43f6a4c4$1 (AT) newsgroups (DOT) borland.com...
| Quote: |
"Philip Colley" <pjcolley (AT) globalnet (DOT) co.uk> wrote in message
news:43f62f47$1 (AT) newsgroups (DOT) borland.com...
The TIdTCPClient appears to connect, some manger software supplied by
"Tibbo" shows that I have connected and the device LED shows packets
arriving, but I cannot get the server to respond.
Please show your actual code. You are likely using the socket
incorrectly.
For security reasons the Alarm System will not respond until it receives
a
valid login which takes the form of <STX> <command>(params)<CR>.
For example:
procedure WriteCommand(const ACmd, AParams: String);
begin
//...
IdTCPClient1.IOHandler.Write(#2+ACmd+AParams+#13);
//...
end;
Or:
procedure WriteCommand(const ACmd, AParams: String);
var
LBuf: TIdBytes;
begin
//...
SetLength(LBuf, 1+Length(ACmd)+Length(AParams)+1);
LBuf[0] := $02;
CopyTIdString(ACmd, LBuf, 1);
CopyTIdString(AParams, LBuf, 1+Length(ACmd));
LBuf[Length(LBuf)-1] := $0D;
IdTCPClient1.IOHandler.Write(LBuf);
//...
end;
Or:
procedure WriteCommand(const ACmd, AParams: String);
begin
//...
with IdTCPClient1.IOHandler do
begin
Write(Byte($02));
Write(ACmd);
Write(AParams);
Write(Byte($0D));
end;
//...
end;
I've used the same format as the serial version and sent by calling
"IdTCPClient1.IOHandler.WriteLn(^C+LI1234+^M)"
WriteLn() appends the data with a CRLF at the end. As such, you are
writing too many characters to the connection.
and various other forms of the Write method.
Please show your actual code.
I've got basic event sets up to register if "OnWork", "OnWorkBegin" and
"OnWorkEnd" but they are never called
The OnWork and OnWorkEnd events are only triggered when the OnWorkBegin
event has been triggered first. OnWorkBegin is only triggered for
operations that require multiple reads/writes internally, such as
reading/writing streams. Reading/writing individual values do no trigger
the events.
If I do a IOHandler.ReadLn after the write the program just sits
non responsive waiting.
By default, ReadLn() expects the data to be terminated by LF, which is not
the case in this situation. The data is terminated by CR instead. Are
you specifying CR as the ATerminator for ReadLn()?
I was hopping that this would operate the same as the Comport version
where the component automatically notifies me when data arrives.
Indy is not an asynchronous library. Operations block the calling thread
until they complete (or an error occurs). In order to process incoming
packets asynchronously using Indy, you will have to move the reading into
a timer or worker thread (I would suggest a thread). Otheerwise, swwitch
to an asynchronous library, such as ICS (http://www.overbyte.be).
To me this points to the login not being formatted correctly
That is hard to say without seeing your actual code.
Gambit
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|