Indy Step by Step - Part 2.2 The TIdTCPServer in detail(1分)

A

aq13

Unregistered / Unconfirmed
GUEST, unregistred user!
Once we have finished the explanations for threading model. we will look "in deep" on the TIdTcpServer component. For now, you can look at the bellow table where the TIdTcpServer properties are explained:

Property Details

Active
When Active property is true, the server is able to handle incoming connections (is started). When it is false, the server is inactive.


Command Handlers
CoomandHandlers is a collection of text commands that will be processed by the server. This property greatly simplify the process of writing servers based on text protocols.


CommandHandlersEnbaled
When it is set to true, the server will work with defined CommandHandlers. If it is false, the entire communication will be handeled by the OnExecute event( this aspects are discussed bellow)


DefaultPort
Is the port that will be listened by the server.


Greeting
It is the Greeting message definition.


MaxConnections
This is the maximum number of parallel connections allowed. If this value is 0, the server will not limit the number of paralel connections. If it is greater than 0, the server will respont with MaxConnectionsReply when the no. of connections are greater than allowed no. of connections.


MaxConnectionsReply
The message that will be sent when a client try to connect to the server and the no. of connections is greater than the no. of allowed connections


ReplyUnnknownCommand
This message is send to the client when the client try to execute an inexistent command. The CommandHandlersEnabled property must be true. If it is set to false, this property is ignored.


TerminateWaitTime
This is the no. of miliseconds that the server should wait to terminate active threads(when you stop the server).



This properties are the most important. You will work whith them every time when you will create servers. As you have saw, you are able to work with indy servers using 2 modes. First mode is with CommandHandlers. This mode greatly simplifies the mode you develop a text based protocol. Let me explain a little bit using an example:
Let's develop a server that implements 2 commands: hello and add. When a client send a hello command the server simply will respond with "Hi!". The add command is little different, because it can have many parameters and the server will respond with the sum of the parameters passed by this command. The format we will use for this command is:
add no1 no2 ... noN
and the server will respond with:
no1+no2+...+noN (the sum of all numbers)

Now we will implement this server. Put a TIdTCPServer on the form set it's active property to true, Default port to 1111 and CommandHandlesEnabled to true. Now, open the collection editor of the CommandHandlers and add 2 new items. For first item fill the Command property with the name of our first command (Hello). Also, for this command set the ReplyNormal Text property with the response text ("HI!"). Now the first command is implemented.
For the second item fill the Command property with "add". It is time to write a little code... In the ObjectInspector click on the events tab anddo
ubleclick on the OnCommand item. And now, the coding part:
procedure TForm1.IdTCPServer1CommandHandlers1Command(ASender: TIdCommand);
var
i:integer;
f:float;
begin

f:=0;
for i:=0 to ASender.Params.Count-1do

f:=f+strtofloat(ASender.Params);
ASender.Thread.Connection.Writeln(floattostr(f));
end;

...And that's all folks! Test your server with the telnet program and you will see thats all works fine. I know that we haven't implement an error handling procedure, but for our scope this example is almost sufficient.
Looking on the code we have writed you will observer the following:
1. We have a strange ASender property
2. We have for this ASender some properties like Params and Connection
3. In the final, for sending a string over a TCP/IP connection we are using the Writeln method of the connection property.
Seems to be simple.The strange ASender is our client connected. Remember our discussion about indy threads? For each client connected to the server a new thread is created. In our case, the ASender property represent our client. ASender property has many properties, but the most important is the Connection property that represent, as you maybe imagine, our connection with the client. Over this connection, we can send Strings, Integer Values, records etc. In fact, using methods defined for Connection property you can send, in fact, any data. In the table bellow you have all methods used for communicating with client.

Property Details
Write Write a string. Similar to write for files

Read
Read a string. Similar with read for files.



WriteLn
Write a string with < CR > terminator. Similar with Writeln for files



ReadCardinal(AConvert:boolean)
Read a cardinal(32 bit unsigned) value. If AConvert is true, the value is converted to Internet Byte order from the Native Intel Byte order. If not, no connevrsion isdo
ne



WriteCardinal(AValue:Cardinal;AConvert:boolean)
Write a cardinal(32 bit unsigned) value. If AConvert is true, the value is converted to Internet Byte order from the Native Intel Byte order. If not, no connevrsion isdo
ne



ReadInteger(AConvert:boolean)
Read an integer value. If AConvert is true, the value will be converted from Internet to Intel byte-order.



WriteInteger(AValue:integer;
AConvert:boolean)
Write an integer value. If AConvert is true, the value will be converted from Internet to Intel byte-order.



ReadBuffer(ABuffer;AByteCount:longint)
Read a buffer. ABuffer is the buffer we want to read and AByteCount is the size of the buffer we are reading.



WriteBuffer(ABuffer;AByteCount:longint;
AWriteNow:boolean)
Send a buffer to the peer . ABuffer is the buffer we want to read and AByteCount is the size of the buffer we are reading. AWriteNow is a boolean value thats indicate if the data contained in buffer will be writed imediatly, ignoring indy buffering mechanism. By default this value is false.



ReadStream (AStream:TStream;AByteCount:longint;AReadUntilDisconnect:boolean)
Read a stream. AStream is the stream we want to read and AByteCount is the size of the stream we are reading. Default value for AByteCount is -1. AReadUntilDisconnect is a boolean value. If it is set tu true the stream will be readed until the connected property will be set to false (when disconnected the reading of the stream will bedo
ne).



WriteStream (AStream:TStream;AAll:boolean;AWriteByteCount:boolean)
Write a stream. AStream is the stream we want to send.
When AAll is true, the stream will be writed from it's begin
ing. When is set to false, the stream will be writed from it's current position. When AWriteByteCount is set to true, the size of the stream will be send to the peer connection. When it is false, the size of the stream will not be send.




These are the most important methods of the Connection property. You will use these methods every time when you will create servers or clients. And, most important, you have to know what each methoddo
es.
When I have saw for the first time the indy architecture, my mind was gone to thedo
s time. Remember how looks a program writed in Turbo Pascal? Let's see:
program Sum;
var a, b: real;
begin

Write('A=');
ReadLn(A);
Write('B=');
Readln(B);
a:=a+b;
Write ('The Sum is:');
Writeln(a);
end.

I was surprised when I have discovered indy. It's programming maneer is the same, but the results are great. You can observe the elegance of indy by creating any TCP/Ip enabled Client/Server applications.
In the next episode, we will discuss a little about TIdTcpClient component and then
will follow practical examples. Stay with Indy!
 
顶部