BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Simple TCP Client/Server problem - can't figure out

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock
View previous topic :: View next topic  
Author Message
Muzzy
Guest





PostPosted: Tue Dec 16, 2003 6:48 pm    Post subject: Simple TCP Client/Server problem - can't figure out Reply with quote



Hello,

I just wonder if you can help me:

I need to create a simple client-server where client, say every 1
second, sends a message "MSG_UPDATE" to server, and server sends a
screen image in compressed .bmp.

I just can't figure out the communication process:

1. How client sends a message to server? I've seen some funcs: SendCMD,
WriteLn, etc. - which to use?

2. What evetn fires on server when it needs to read a messsage from
client? I assumed - OnExecute. Am i right?

3. When server sends data, i use following in Server.OnExecute method:

with AThread.connection do begin
...
Try
OpenWriteBuffer;
WriteStream(CStream);
CloseWriteBuffer;
CStream.Free;
...

But how about when server sends a large amount of data and CStream
contains more data that a socket buffer can hold? Does WriteStream send
all the stream or a part?

4. When should client read data from server? When OnWork event is fired?
What method to use? ReadLn or ReadStream?


I just miss a general concept - that's my problem... I try to use Indy
help and FAQ, but probably it's sort of a language barreer or just my
brains issue :)


ANY help would be appreciated!

Thank you,
Andrey

Back to top
Jack Mays
Guest





PostPosted: Tue Dec 16, 2003 7:07 pm    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote




"Muzzy" <leyandrew (AT) yahoo (DOT) com> wrote

Quote:
Hello,

I just wonder if you can help me:

I need to create a simple client-server where client, say every 1
second, sends a message "MSG_UPDATE" to server, and server sends a
screen image in compressed .bmp.

I just can't figure out the communication process:

1. How client sends a message to server? I've seen some funcs: SendCMD,
WriteLn, etc. - which to use?

Generally you want to use WriteLn, i'm not familiar with the SendCMD
command.

Quote:
2. What evetn fires on server when it needs to read a messsage from
client? I assumed - OnExecute. Am i right?

Yes, you are correct.

Quote:
3. When server sends data, i use following in Server.OnExecute method:

with AThread.connection do begin
...
Try
OpenWriteBuffer;
WriteStream(CStream);
CloseWriteBuffer;
CStream.Free;
...

But how about when server sends a large amount of data and CStream
contains more data that a socket buffer can hold? Does WriteStream send
all the stream or a part?

IIRC, the default buffer is 8k, so anything more than that and you will need
to have a loop, counting the bytes received untill you reach the file/data
size you are transmitting. Also, you will want to send a plain text string
message telling the client the total size of what is being sent.

Quote:
4. When should client read data from server? When OnWork event is fired?
What method to use? ReadLn or ReadStream?

The TCPClient would be best off in a "reader thread"(a seperate thread that
just calls IdTCPClient.ReadLn in it's Excute event to read the data and pass
it to the main VCL thread VIA PostMessage. Just the group archive from a
post my Martin James (or maybe that was emailed to me), but it descripbes
how to have a reader thread. I'll check and email it to you if i can find
it.

Quote:
I just miss a general concept - that's my problem... I try to use Indy
help and FAQ, but probably it's sort of a language barreer or just my
brains issue Smile
ANY help would be appreciated!

Thank you,
Andrey




Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Dec 16, 2003 7:27 pm    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote



"Muzzy" <leyandrew (AT) yahoo (DOT) com> wrote


Quote:
1. How client sends a message to server? I've seen some funcs:
SendCMD, WriteLn, etc. - which to use?

I assume you are using Indy then, correct? For something as simple as just
a string, WriteLn() will work fine. Then the server can call ReadLn() to
read it.

Quote:
2. What evetn fires on server when it needs to read a
messsage from client? I assumed - OnExecute. Am i right?

There is no specific OnRead type of event for that. Indy is not an
event-driven library like many other socket components are. However,
assuming you are using TIdTCPServer, then yes, OnExecute would be the most
appropriate place for it. Or you could alternative use the CommandsHandlers
collection instead, and just assign an event handler to the specific command
that you want to handle.

Quote:
But how about when server sends a large amount of data and
CStream contains more data that a socket buffer can hold?
Does WriteStream send all the stream or a part?

WriteStream() sends the entire stream in full, although internally it will
send it in smaller pieces to accomodate the socket's internal buffering.
Likewise, ReadStream() will read the entire stream in full.

I should also mention that if you are going to be sending large amounts of
data, you may not want to use write buffering like you currently are. Since
you did not provide any Threshold parameter to OpenWriteBuffer(), the entire
stream contents will be buffered into memory before then being sent to the
socket. If you are serving large amounts of data, then that will be a lot
of memory used. If you store your data into a TMemoryStream, for example,
then the data is already in memory and you don't need to buffer it a second
time. Otherwise, you should always provide some kind of Threshold value to
OpenWriteBuffer() so that the memory buffer can be flushed to the socket
periodically. Write buffering makes sense for smaller amounts of data,
especially if you want to support cancelling the writing before it actually
happens. That is harder to manage for larger amounts of data.

Quote:
4. When should client read data from server?

Whenever data is actually available. There is no event for that, so the
client will just have to poll the socket periodically in a timer or thread.
Alternatively, if you are expecting a response immediately after sendind the
command, then just start reading the socket immediately after sending the
command.

Quote:
When OnWork event is fired?

No. OnWork is triggered only during the actual reading, not before. Again,
Indy (especially clients) is not an event-driven library.

Quote:
What method to use? ReadLn or ReadStream?

If you send the data with WriteStream(), then use ReadStream() to read it.


Gambit



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Dec 16, 2003 7:31 pm    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote

"Jack Mays" <jackmaysNO (AT) SPAMsupplant (DOT) net> wrote


Quote:
Generally you want to use WriteLn, i'm not familiar with the
SendCMD command.

SendCmd() is just like WriteLn(), except that it does not return until the
receiver actually responds with a numeric response code before sending any
further data. SendCmd() can then check that response code against a
user-supplied list of acceptable values, and will throw an exception if the
response does not match any of them. Protocols such as POP3, SMTP, HTTP,
for example, use a command/response architecture like that, so SendCmd() is
useful for them.

Quote:
IIRC, the default buffer is 8k, so anything more than that
and you will need to have a loop

If you were writing to the socket directly, then yes. However,
WriteStream() already does that looping internally for you, so you do not do
it yourself at all. All you have to do is provide the stream and Indy does
the rest automatically.

Quote:
Also, you will want to send a plain text string message telling
the client the total size of what is being sent.

WriteStream() already handles that as well. It has an AWriteByteCount
parameter that specifies whether the stream's size should be send first
before the stream data, or not at all.


Gambit



Back to top
Muzzy
Guest





PostPosted: Tue Dec 16, 2003 8:38 pm    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote

Remy Lebeau (TeamB) wrote:
Quote:
"Muzzy" <leyandrew (AT) yahoo (DOT) com> wrote in message
news:3fdf5374$1 (AT) newsgroups (DOT) borland.com...


1. How client sends a message to server? I've seen some funcs:
SendCMD, WriteLn, etc. - which to use?


I assume you are using Indy then, correct? For something as simple as just
a string, WriteLn() will work fine. Then the server can call ReadLn() to
read it.


2. What evetn fires on server when it needs to read a
messsage from client? I assumed - OnExecute. Am i right?


There is no specific OnRead type of event for that. Indy is not an
event-driven library like many other socket components are. However,
assuming you are using TIdTCPServer, then yes, OnExecute would be the most
appropriate place for it. Or you could alternative use the CommandsHandlers
collection instead, and just assign an event handler to the specific command
that you want to handle.


But how about when server sends a large amount of data and
CStream contains more data that a socket buffer can hold?
Does WriteStream send all the stream or a part?


WriteStream() sends the entire stream in full, although internally it will
send it in smaller pieces to accomodate the socket's internal buffering.
Likewise, ReadStream() will read the entire stream in full.

I should also mention that if you are going to be sending large amounts of
data, you may not want to use write buffering like you currently are. Since
you did not provide any Threshold parameter to OpenWriteBuffer(), the entire
stream contents will be buffered into memory before then being sent to the
socket. If you are serving large amounts of data, then that will be a lot
of memory used. If you store your data into a TMemoryStream, for example,
then the data is already in memory and you don't need to buffer it a second
time. Otherwise, you should always provide some kind of Threshold value to
OpenWriteBuffer() so that the memory buffer can be flushed to the socket
periodically. Write buffering makes sense for smaller amounts of data,
especially if you want to support cancelling the writing before it actually
happens. That is harder to manage for larger amounts of data.


4. When should client read data from server?


Whenever data is actually available. There is no event for that, so the
client will just have to poll the socket periodically in a timer or thread.
Alternatively, if you are expecting a response immediately after sendind the
command, then just start reading the socket immediately after sending the
command.


When OnWork event is fired?


No. OnWork is triggered only during the actual reading, not before. Again,
Indy (especially clients) is not an event-driven library.


What method to use? ReadLn or ReadStream?


If you send the data with WriteStream(), then use ReadStream() to read it.



Do ReadLn and WriteLn fire any exceptions if peer is disconected?
Also are the blocking? Say if i put

Result := TcpClient.ReadLn();

Would it wait until server sends something or returns immediately?

Thank you,
Andrey




Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Dec 16, 2003 9:15 pm    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote


"Muzzy" <leyandrew (AT) yahoo (DOT) com> wrote


Quote:
Do ReadLn and WriteLn fire any exceptions if peer is disconected?

It is possible, yes.

Quote:
Also are the blocking?

Yes. Indy uses blocking sockets for everything.

Quote:
Result := TcpClient.ReadLn();

Would it wait until server sends something

Yes, or until a timeout occurs.


Gambit



Back to top
Tony Caduto
Guest





PostPosted: Wed Dec 17, 2003 12:38 am    Post subject: Re: Simple TCP Client/Server problem - can't figure out Reply with quote

for the commands you can use writeln, then to transfer the image use
sendstream.

For the client you need to create a read thread that just sits in a while
loop waiting for commands, then use postmessage to update stuff in the main
vcl thread.



"Muzzy" <leyandrew (AT) yahoo (DOT) com> wrote

Quote:
Hello,

I just wonder if you can help me:

I need to create a simple client-server where client, say every 1
second, sends a message "MSG_UPDATE" to server, and server sends a
screen image in compressed .bmp.

I just can't figure out the communication process:

1. How client sends a message to server? I've seen some funcs: SendCMD,
WriteLn, etc. - which to use?

2. What evetn fires on server when it needs to read a messsage from
client? I assumed - OnExecute. Am i right?

3. When server sends data, i use following in Server.OnExecute method:

with AThread.connection do begin
...
Try
OpenWriteBuffer;
WriteStream(CStream);
CloseWriteBuffer;
CStream.Free;
...

But how about when server sends a large amount of data and CStream
contains more data that a socket buffer can hold? Does WriteStream send
all the stream or a part?

4. When should client read data from server? When OnWork event is fired?
What method to use? ReadLn or ReadStream?


I just miss a general concept - that's my problem... I try to use Indy
help and FAQ, but probably it's sort of a language barreer or just my
brains issue :)


ANY help would be appreciated!

Thank you,
Andrey




Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.