ReadLine
15 answers - 888 bytes -

Hello,
I'm using TWSocket for UDP communications, so far it works quite good.
Now I have the problem that at one place in the program I need
synchronus communication. I send out one byte and if I receive the same
byte within some short timeout, I assume that the device I'm talking to
has a echo mode.
If I use ReadLine with a 50 ms timeout, my program handg, until the
close button is pressed (x right corner of the window). Then is
continues but hasn't read anything. If I don't press that button it
doesn't continue!
How to use ReadLine properly? In the help was something with Wait
statet, but the property where you should assign that wait object to
doesn't exist (any more).
Do you have a short sample?
I'm using D2005 Arch. SP1 german on Windows XP SP2.
Greetings
Markus
No.1 | | 1335 bytes |
| 
As expressed in the source code, ReadLine is deprecated. Anyway, it doesn't
fit correctly with UDP protocol which is datagram oriented. Using "lines"
with such protocol is strange.
Now I have the problem that at one place in the program I need
synchronus communication. I send out one byte and if I receive the same
byte within some short timeout, I assume that the device I'm talking to
has a echo mode.
Send your byte then program a loop waiting for the evnt DataAvailable to
occur before a given time. Not the best practice, but that's how you can
implement synchronous operation if you really need this (you can ALWAYS
avoid synchronous operation).
When you are in your wait loop, you must process events or your application
will be locked. You must do something like that (not checked, out of my
head) :
FReceiveFlag := FALSE;
WSocket1.Send(your one byte data );
while not FReceiveFlag do begin
DummyHandle := INVALID_HANDLE_VALUE;
MsgWaitForM(0, DummyHandle, FALSE, 1000,
QS_ALLINPUT + QS_ALLEVENTS +
QS_KEY + QS_MUSE);
Application.ProcessMessages;
if Application.Terminated then
break;
end;
DataAvailable handler will set the FReceiveFlag variable to TRUE.
You can also use a TTimer to check for timeout.
No.2 | | 2051 bytes |
| 
Francois PIETTE schrieb:
As expressed in the source code, ReadLine is deprecated. Anyway, it doesn't
fit correctly with UDP protocol which is datagram oriented. Using "lines"
with such protocol is strange.
>>Now I have the problem that at one place in the program I need
>>synchronus communication. I send out one byte and if I receive the same
>>byte within some short timeout, I assume that the device I'm talking to
>>has a echo mode.
Send your byte then program a loop waiting for the evnt DataAvailable to
occur before a given time. Not the best practice, but that's how you can
implement synchronous operation if you really need this (you can ALWAYS
avoid synchronous operation).
When you are in your wait loop, you must process events or your application
will be locked. You must do something like that (not checked, out of my
head) :
FReceiveFlag := FALSE;
WSocket1.Send(your one byte data );
while not FReceiveFlag do begin
DummyHandle := INVALID_HANDLE_VALUE;
MsgWaitForM(0, DummyHandle, FALSE, 1000,
QS_ALLINPUT + QS_ALLEVENTS +
QS_KEY + QS_MUSE);
Application.ProcessMessages;
if Application.Terminated then
break;
end;
DataAvailable handler will set the FReceiveFlag variable to TRUE.
You can also use a TTimer to check for timeout.
Thanks for the reply, I will consider that tomorrow.
Normally I do asynchronos communication, but for the first test wether
my communication partner has echo or not I don't want this, I simply
want this one synchronous.
The thing is that the code is in a dll, so application.processmessages
might not work here. does it? The timeout will be rather short anyhow
(ca. 50 ms) and I think i do it with GetTickCount, which should be
sufficient here and more easy to use than a at this place timer.
is there anything bad with these ideas?
Greetings
Markus Humm
No.3 | | 905 bytes |
| 
The thing is that the code is in a dll, so application.processmessages
might not work here. does it?
It depend on the caller of the DLL ! You may as well be called from a
thread. Calling the message pump from a DLL is risky when you don't know
anything about the calling process. If you have to write a DLL that works in
all (well most) cases, then you should probably put all your stuff into a
separate thread with his own message pump. The function exposed by the DLL
would create the thread suspended, pass all parameters, resume the thread
and wait until the thread terminate, then return to the caller. Within the
thread, you can do almost what you want, including calling the thread's own
message pump. You have to have a message pump or the ICS component will not
work within a thread. There are several samples with components running in a
thread.
No.4 | | 1082 bytes |
| 
[snip]
>>
>>The thing is that the code is in a dll, so application.processmessages
>>might not work here. does it? The timeout will be rather short anyhow
>>(ca. 50 ms) and I think i do it with GetTickCount, which should be
>>sufficient here and more easy to use than a at this place timer.
>is there anything bad with these ideas?
So far the dll works (ICS asynchronous transfer included), as the
calling application is a Delphi one which calls
application.processmessages from time to time.
Do I really need a message pump in this case? I think not, since the
program never spends long times in the dll, because the data is given
back to the caller very fast via callbacks.
But: in the near future the caller will be another dll. What's then?
I don't know whether this part of the program will contain more than a
starter stub later. Who needs a message pump then?
Now you've worried me a bit
Greetings
Markus
No.5 | | 1323 bytes |
| 
Do I really need a message pump in this case?
You always need a message pump for ICS component (except TPing component) to
work. Without message pump, no winsock event !
I think not, since the
program never spends long times in the dll, because the data is given
back to the caller very fast via callbacks.
Windows as the ability to handle 500.000 messages per second on a today's
desktop computer. So "long time" is very relative. 100 mS can be a long
time.
But: in the near future the caller will be another dll. What's then?
I don't know whether this part of the program will contain more than a
starter stub later. Who needs a message pump then?
You _always_ need a message pump. If the calling program doesn't provide
one, you must provide one and to have one without interfering with the
calling DLL it is better to have all you stuff in a thread. Consider a
thread as a program within a program.
If you don't want to have a thread, you must ask the host application to
provide a hook for Application.ProcessMessages (or equivalent if the host
application is written using another language). You can do that by using a
callback.
Now you've worried me a bit
Sorry. You are now back to reality.
No.6 | | 842 bytes |
| 
You _always_ need a message pump. If the calling program doesn't provide
one, you must provide one and to have one without interfering with the
calling DLL it is better to have all you stuff in a thread. Consider a
thread as a program within a program.
If you don't want to have a thread, you must ask the host application to
provide a hook for Application.ProcessMessages (or equivalent if the host
application is written using another language). You can do that by using a
callback.
>>Now you've worried me a bit
Sorry. You are now back to reality.
Hm, could that message pump be realised by a timer in the dll where the
application.processmessages is called each onTimer event?
Greetings
Markus
No.7 | | 1030 bytes |
| 
You _always_ need a message pump. If the calling program doesn't provide
one, you must provide one and to have one without interfering with the
calling DLL it is better to have all you stuff in a thread. Consider a
thread as a program within a program.
If you don't want to have a thread, you must ask the host application to
provide a hook for Application.ProcessMessages (or equivalent if the host
application is written using another language). You can do that by using a
callback.
Hm, could that message pump be realised by a timer in the dll where the
application.processmessages is called each onTimer event?
Defenitely not. Depending on the network traffic, you could easily have something like one thousand
messages per second in the queue. The message loop must run full speed.
As I said, you must either provide a callback to the DLL to call the application's message pump, or
have you own thread with his own message queue and message pump (easier).
No.8 | | 1354 bytes |
| 
Message
From: "Markus Humm" <markus.humm (AT) freenet (DOT) de>
To: "ICS support mailing" <twsocket (AT) elists (DOT) org>
Sent: Monday, May 02, 2005 6:29 AM
Subject: Re: [twsocket] ReadLine
>>
>You _always_ need a message pump. If the calling program doesn't provide
>one, you must provide one and to have one without interfering with the
>calling DLL it is better to have all you stuff in a thread. Consider a
>thread as a program within a program.
>>
>If you don't want to have a thread, you must ask the host application to
>provide a hook for Application.ProcessMessages (or equivalent if the host
>application is written using another language). You can do that by using
>a
>callback.
>>
>>
Now you've worried me a bit
>>
>>
>Sorry. You are now back to reality.
>>
Hm, could that message pump be realised by a timer in the dll where the
application.processmessages is called each onTimer event?
Greetings
Markus
Hehe, TTimer relies on messages also.
Dan
No.9 | | 747 bytes |
| 
Francois Piette schrieb:
Defenitely not. Depending on the network traffic, you could easily have something like one thousand
messages per second in the queue. The message loop must run full speed.
As I said, you must either provide a callback to the DLL to call the application's message pump, or
have you own thread with his own message queue and message pump (easier).
, timer doesn't work for another reason: the timer component needs
messages itsself so doesn't fire.
Setting up a thread and simply execute application.processmessages in it
over and over doesn't work either.
How has that messagepump to look like? Any example?
Greetings and thanks so far
Markus
No.10 | | 920 bytes |
| 
Defenitely not. Depending on the network traffic, you could easily have
something like one thousand messages per second in the queue.
The message loop must run full speed.
As I said, you must either provide a callback to the DLL to call the
application's message pump, or have you own thread with his
own message queue and message pump (easier).
, timer doesn't work for another reason: the timer component needs
messages itsself so doesn't fire.
Setting up a thread and simply execute application.processmessages in it
over and over doesn't work either.
In a thread, you doesn't call Application.ProcessMessages but the own
message pump of the thread that you must first create.
How has that messagepump to look like? Any example?
Look into IcsDll1.pas delivered with ICS (there are othe rmultithreaded
sample, just do a search)
No.11 | | 195 bytes |
| 
Hello ;-) It's me again
Just one little question
When i have a TList of busy HTTPCli'ents how do i know which one should i
remove on RequestDone event?
Thank you,
Ann
No.12 | | 175 bytes |
| 
When i have a TList of busy HTTPCli'ents how do i know which one should i
remove on RequestDone event?
The Sender parameter is the one that triggered the event.
No.13 | | 504 bytes |
| 
Just one little question
When i have a TList of busy HTTPCli'ents how do i
know which one should i
remove on RequestDone event?
You have the sender argument in RequestDone. It's the Http component that sent the event. You can
cast it to THttpCli and do whatever you like.
btw: This is basic Delphi programming. The sender argument of any event always refers to the
component source of the event. You always need it when the same handler is used for many components.
No.14 | | 1059 bytes |
| 
yes but im not asking about sender but how do i find this sender in tlist of
components
do i have to make something like this or is there easier way?
for i:=0 to list.item.count-1 do
begin
if list.item[i] = sender then this_is_the_one?
break;
end;
Message
From: "Francois Piette" <francois.piette (AT) overbyte (DOT) be>
To: "ICS support mailing" <twsocket (AT) elists (DOT) org>
Sent: Tuesday, May 03, 2005 11:26 AM
Subject: Re: [twsocket] Little question TList of HTTPCli
Just one little question
When i have a TList of busy HTTPCli'ents how do i
know which one should i
remove on RequestDone event?
You have the sender argument in RequestDone. It's the Http component
that sent the event. You can
cast it to THttpCli and do whatever you like.
btw: This is basic Delphi programming. The sender argument of any event
always refers to the
component source of the event. You always need it when the same handler is
used for many components.
No.15 | | 16 bytes |
| 
You have TList.I