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 

Give me some idea.

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





PostPosted: Thu Oct 23, 2003 5:01 am    Post subject: Give me some idea. Reply with quote



i need to create a Server & Client with Indy component.

My server will need to send command to Client to order it to performance
some job.
Example. Send 'shutdown' to client, then Client will shutdown the PC.
or another way, Send 99, to client to do the same things. (let say 99 means
shut down)

Question 1. Can someone tell me which method is suitable, or any other
method is the best choice?

Question 2. How if sometimes i need to send command 99, 88, 11, and
sometimes the certain command
are passed with parameters in string.

Example: command 88 will show a message dialog, but we need to pass 88 with
'Hi, this is testing' string
or just send everything in string, and extract the meanings from the string?

Question 3. Performance issues on different methods?


thanks in advance


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Oct 23, 2003 5:31 am    Post subject: Re: Give me some idea. Reply with quote




"cks" <chuaks (AT) dynabook (DOT) com.my> wrote


Quote:
Question 1. Can someone tell me which method is suitable,
or any other method is the best choice?

That depends on what kind of data you want to send with each command, if
any. If all you want is simple commands with no data, then
Read/WriteInteger() or Read/WriteLn() will work fine.

Quote:
Question 2. How if sometimes i need to send command 99, 88, 11,
and sometimes the certain command are passed with parameters in string.

One way would be to just put everything into a single string and use
Read/WriteLn(). Anotehr way is to use Read/WriteStrings(), with each string
being a different parameter. Another way would be to put everything into a
structure and then use Read/WriteBuffer(). Another alternative is to use
Read/WriteRFCReply().

It really comes down to what exactly you need to send for each commands, so
that you can come up with some kind of common formatting for all of them.

Quote:
Question 3. Performance issues on different methods?

Again, it depends on what exactly you are sending.


Gambit



Back to top
Ioan Ghip
Guest





PostPosted: Thu Oct 23, 2003 5:31 am    Post subject: Re: Give me some idea. Reply with quote




Quote:
Question 2. How if sometimes i need to send command 99, 88, 11, and
sometimes the certain command
are passed with parameters in string.

Example: command 88 will show a message dialog, but we need to pass 88
with
'Hi, this is testing' string
or just send everything in string, and extract the meanings from the
string?


type
{the Communication Block used in both parts (Server+Client)}
TCommBlock = record
Command: integer;
DESTINATIONSERVER: string[128];
end;

const
_SHUTDOWN_ = 88;

{if the client send the command}
procedure TForm1.Button1Click(Sender: TObject);
var
client: TIdTCPClient;
SndCmd: TCommBlock;
begin
FillChar(SndCmd, sizeof(RecCmd), #0);
client := TIdTCPClient.Create(nil);
try
{set the connection prop.}
client.Host := '127.0.0.1';
client.Port := 8090;
client.Connect(5000);
{send informations}
SndCmd.Text := 'bye bye';
SndCmd.Command := _SHUTDOWN_;
client.WriteBuffer(SndCmd, SizeOf(SndCmd));
client.Disconnect;
finally
client.Free;
end;
end;

and on the server side (in the OnExecute event of IdTCPServer):

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecCmd: TCommBlock;
begin
try
if not AThread.Terminated and AThread.Connection.Connected then
begin
FillChar(RecCmd, sizeof(RecCmd), #0);
AThread.Connection.ReadBuffer(RecCmd, SizeOf(RecCmd));
if RecCmd.Command = _SHUTDOWN_ then
begin
// do the shut down
end;
end;
except
on e: EIdConnClosedGracefully do
exit; // obvious..
on e: Exception do
begin
if e is EIdSocketError then
raise;
end;
end;
end;

-ioan



Back to top
Ioan Ghip
Guest





PostPosted: Thu Oct 23, 2003 5:33 am    Post subject: Re: Give me some idea. Reply with quote


Quote:
type
{the Communication Block used in both parts (Server+Client)}
TCommBlock = record
Command: integer;
DESTINATIONSERVER: string[128];
end;


"DESTINATIONSERVER" change that with "Text" <g>

-i



Back to top
Colonel Tony
Guest





PostPosted: Thu Oct 23, 2003 5:58 am    Post subject: use a tstringlist Reply with quote

use a tstringlist, then send the commatext with writeln

i.e.
mystringlist.values['command']:= '88';
mystringlist.values['msgstr']:=''Hi, this is testing string';

to send to the server do

myclient.writeln(mystringlist.commatext);
what gets sent across the wire is:
command=88,msgstr="Hi, this is testing string"

if you need to send a multi line message use another tstringlist or
descendent and assign it's commatext to the msgstr value of the first.

mystringlist.values['msgstr']:= memo1.lines.commatext;

Then on the other side create a recieving stringlist and set the commatext

commandlist.commatext:= athread.connection.readln('',5000);
if commandlist.values['command'] = '88' then
begin
//do something with the message
end;


or you could just use readinteger and writeinteger to send just the bytes
for the command.
Either way it's all very easy to do with blocking sockets.

Performance for the stringlist method is good and it is easy to understand
and read the code. Also using stringlists has much less bloat than some xml
based protocols, and you could easily compress your stringlist and stream it
over if you have alot of params/text :-)

Hope this helps you out.

Tony


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Oct 23, 2003 6:04 am    Post subject: Re: Give me some idea. Reply with quote


"Ioan Ghip" <aaabbb (AT) ccc (DOT) com> wrote



(Typo aside) Rather than forcing every packet to include a fixed sized text
field that may or may not be used at all let alone filled to capacity, you
could use a dynamic-sized field instead. For example:

type
TCommHeader = packed record
Command: Integer;
DataSize: Integer;
end;

TCommBlock = packed record
Header: TCommHeader;
Data: String;
end;

const
CMD_MSGBOX = 88;


--- Client ---

procedure SendCommBlock(AConn: TIdTCPConnection; var SndCmd:
TCommBlock);
begin
AConn.WriteBuffer(SndCmd.Header, SizeOf(SndCmd.Header));
if SndCmd.Header.DataSize > 0 then AConn.Write(SndCmd.Data);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
SendCmd: TCommBlock;
begin
//...
SndCmd.Data := 'bye bye';
SndCmd.Header.Command := CMD_MSGBOX;
SndCmd.Header.DataSize := Length(SndCmd.Data);
SendCommBlock(IdTCPClient1, SndCmd);
//..
end;


--- Server ---

procedure ReadCommBlock(AConn: TIdTCPConnection; var RecCmd:
TCommBlock);
begin
AConn.ReadBuffer(RecCmd.Header, SizeOf(RecCmd.Header));
if RecCmd.Header.DataSize > 0 then RecCmd.Data :=
AConn.ReadString(RecCmd.Header.DataSize);
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecCmd: TCommBlock;
begin
//...
ReadCommBlock(Athread.Connection, RecCmd);

if RecCmd.Command = CMD_MSGBOX then
begin
Windows.MessageBox(nil, PChar(RecCmd.Data), 'Client Message',
MB_OK);
end;

//...
end;


Gambit


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Oct 23, 2003 6:18 am    Post subject: Re: use a tstringlist Reply with quote


"Colonel Tony" <tcaduto (AT) amsoftwaredesign (DOT) com> wrote

Quote:
use a tstringlist, then send the commatext with writeln

The alternative is use Read/WriteStrings() instead of ReadWriteLn().


Gambit



Back to top
cks
Guest





PostPosted: Thu Oct 23, 2003 7:04 am    Post subject: Another questions Reply with quote

if i have many commands need to be identify,
is it good to code everything inside the IdTCPServer1Execute

means inside the IdTCPServer1Execute will have a lot of if (or case)
if cmd = '88'
...
if cmd = '89'
...
if cmd = '90'
if msg = 'xxxxx'
....
if msg = 'yyyy'
...
...
...
...

just to figure out whether this is the normal way people doing ALL the
'processess' inside Execute ?
or is there any other way of doing ?


Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Oct 23, 2003 8:17 am    Post subject: Re: Another questions Reply with quote


"cks" <chuaks (AT) dynabook (DOT) com.my> wrote


Quote:
if i have many commands need to be identify,
is it good to code everything inside the
IdTCPServer1Execute

You have to anyway, since that the place where the data will be available
for reading.

Quote:
means inside the IdTCPServer1Execute will have a lot of if (or case)

Better to use a case statement, but yes:

Case cmd of
88: ...
89: ...
90:
if msg = 'xxxxx' ...
if msg = 'yyyy'
end;


Gambit



Back to top
Tony Caduto
Guest





PostPosted: Fri Oct 24, 2003 1:36 am    Post subject: Re: use a tstringlist Reply with quote

Remy Lebeau (TeamB) wrote:

Quote:

"Colonel Tony" <tcaduto (AT) amsoftwaredesign (DOT) com> wrote in message
news:3f977018$1 (AT) newsgroups (DOT) borland.com...
use a tstringlist, then send the commatext with writeln

The alternative is use Read/WriteStrings() instead of ReadWriteLn().


Gambit

Yes, you could sent the stringlist that way as well Smile
I just did it that way and stuck with it.

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.