Indy 10.5.8 for Delphi and Lazarus modified version (2011)

Source: Internet
Author: User

Indy 10.5.8 for Delphi and Lazarus modified (+) Internet Direct (Indy) is a set of open source Internet components that cover almost all popular Internet protocols. was built by a group of developers led by Chad Z Hower, with the Indy 9 in Delphi 7. On its palette, there are altogether more than 100 Indy components installed. Using these components you can develop TCP client and server applications based on a variety of protocols and handle related coding and security issues. The Indy component can be identified by a prefix ID.
Idtcpserver/idtcpclientidtcpserver
Uses Idcontext//need reference
Properties, Method:
Idtcpserver.active: =true; Turn on the server
IdTCPServer1.Bindings.Add.IP: = ' 127.0.0.1 ';//Bind IP
IdTCPServer1.Bindings.Add.Port: = 7956;//bound port
Event:
OnConnect: Client connection successfully triggered
OnDisconnect: Client Disconnect Trigger
OnExeCute: Received client data triggering example
Send data as if all customers were disconnected
Var
I:integer;
Context:tidcontext;
Begin
With IdTCPServer1.Contexts.LockList do
Try
For I: = 0 to Count-1 do
Begin
Context: = Tidcontext (Items[i]);
Context.Connection.IOHandler.Write (' hello,everybody! ');
End
Finally
IdTCPServer1.Contexts.UnlockList;
End
end;//sending data to a customer
Var
I:integer;
Context:tidcontext;
Begin
With IdTCPServer1.Contexts.LockList do
Try
For I: = 0 to Count-1 do
Begin
Context: = Tidcontext (Items[i]);
If Context.Binding.PeerIP <> ' 192.168.10.90 ' then
Continue
Context.Connection.IOHandler.Write (' hello! ');
End
Finally
IdTCPServer1.Contexts.UnlockList;
End
End;idtcpclient
Properties, Method:
ConnectTimeout: Connection timed out
Host: IP or domain name
Ipversion:ip version IPv4 or IPv6
Name: Control Name
Port: Host ports
ReadTimeout: Read timeout
Idtcpclient1.connect; Connecting to the service side
idtcpclient1.disconnect;//End-Open connection
idtcpclient1.connected;//whether the connection succeeded returns True if the connection succeeded
IdTCPClient1.IOHandler.WriteLn (' AA ');//Send data to the server Onwork event Aworkmode=wmread indicates that there is a TCP connection to receive data using Indy in DelPhi2007 (i) First First of all, why use INDY10 the latest INDY10 can be based on the Win32 (Fiber) API.
What is called the Fiber API, here is the explanation:
Fiber (Fiber)-can be from a 32-bit version of Windows? Lightweight threading objects used in-many scenarios are useful. Because threads are valuable resources, you sometimes do not want the entire OS thread to be dedicated to performing simple tasks. By fiber, you can control the scheduling of tasks more tightly than threads, because you are responsible for managing them instead of the OS. Because they have less overhead, they are much faster when you switch contexts.    In addition, because you control fiber, it is often easier to track synchronization issues for them. However, this feature is now only useful for delphi7.
Port overlap allows your server to take on more users. INDY10 is worth a use. INDY10 supports the completion of ports and fibers, with a huge performance boost! ================================================================================ Let's open the DelPhi2007 tool first! First we do a simple client to create a new window program to drag into a TCP client control and 3 buttons a text box is disconnected and occurs setting the properties of the Idtcpclient control host:127.0.0.1
post:3000
Let's do the event on the connection button.
Procedure Tform6.conetclick (Sender:tobject);
Begin
Try
If not (idtcpclient1.connected) then
Idtcpclient1.connect;
ShowMessage (' connection succeeded ');
Except
ShowMessage (' connection failed ');
End
End; Then we'll do the server program.
Create a new window program drag into a TCP server side control two buttons and a TMemo to display information
Bindings 0.0.0.0:3000
Defaultport 3000 Our events on the "Start Service" button procedure Tform6.button1click (sender:tobject);
Begin
idtcpserver1.active:= true;
End, as long as it is set to true when the service is started and shutdown is also set to False
Next we have to deal with IdTCPServer1 's OnExecute event! Select Control EVENTS Column double-click OnExecute
Here the code we write for the time being procedure Tform6.idtcpserver1execute (acontext:tidcontext);
Begin
Exit
End Tidcontext needs uses Idcontext to get here. Run the server and the client and then start the server and connect the server
Well, it's ready to be connected!
But because we exited the server Listening section, we didn't keep the connection.
Now let's change the code. We change the OnExecute code as follows procedure Tform6.idtcpserver1execute (Acontext:tidcontext);
Var
swp:string;
Begin
Try
AContext.Connection.IOHandler.CheckForDisconnect (True, true);
SWP:=ACONTEXT.CONNECTION.IOHANDLER.READLN ();
MEMO1.LINES.ADD (SWP);
Finally
End
End; We also modify the client
Procedure Tform6.conetclick (Sender:tobject);
Begin
Try
If not (idtcpclient1.connected) then
Begin
Idtcpclient1.connect;
IdTCPClient1.IOHandler.writeln (' Lianjie ');
ShowMessage (' connection succeeded ');
End
Except
ShowMessage (' connection failed ');
End
End
Run the test, please.
When the connection button is pressed to add a line of ' Lianjie ' string in the text box on the server and its click on the connection is not valid and just once each click will prompt the connection successfully read the code to find out in the connection when the time to determine whether the connection is already connected if you have to stay connected to the following code! So that the current connection is already maintained! Well, let's send a message to see if we can actually connect.
Events on the Send button
Procedure Tform6.sendclick (Sender:tobject);
Var
str:string;
Begin
Str:=edit1.text;
if (idtcpclient1.connected) then
IdTCPClient1.IOHandler.writeln (STR);
End
Okay, let's test it. Is it really possible to send data to the server after the connection?
See it!          is not able to send the data! Tutorial on using Indy10 TCP Connection in Delphi 2007 (Series II) How does the server differentiate the data from which one is sent, or how the server responds to it? ~ First for reply to the corresponding client sent over the data! The client has accepted and displayed the server feedback back data!
We modify the OnExecute code on the server as follows! Procedure Tform6.idtcpserver1execute (Acontext:tidcontext);
Var
swp:string;
Begin
Try
AContext.Connection.IOHandler.CheckForDisconnect (True, true);
SWP:=ACONTEXT.CONNECTION.IOHANDLER.READLN ();
if (swp<> ") Then
AContext.Connection.IOHandler.WriteLn (' server has received the message you sent: ' +swp);
MEMO1.LINES.ADD (SWP);
Finally
End
End
In the client we add a TMemo to accept the data sent from the server!
Then we are looking at the client code!
The events on the Connect and send buttons are modified to
Procedure Tform6.conetclick (Sender:tobject);
Begin
Try
If not (idtcpclient1.connected) then
Begin
Idtcpclient1.connect;
IdTCPClient1.IOHandler.writeln (' Lianjie ');
STR:=IDTCPCLIENT1.IOHANDLER.READLN ();
MEMO1.LINES.ADD (STR); ShowMessage (' connection succeeded ');
End
Except
ShowMessage (' connection failed ');
End
End;procedure Tform6.sendclick (Sender:tobject);
Var
str:string;
Begin
Str:=edit1.text;
if (idtcpclient1.connected) then
IdTCPClient1.IOHandler.writeln (STR);
Try
STR:=IDTCPCLIENT1.IOHANDLER.READLN ();
MEMO1.LINES.ADD (STR);
Finally
End
End
After we compile and open more than one client to test, we will find that the different client servers will respond separately and not interfere with their reply content!
Do this here you also know that the client should send a data to the corresponding to read a piece of data! Some people might think of using a timer to read the data regularly! ~ This is also a way! However, in the program operation because the data is too fast to read in time, there will be data loss! So what are we going to do to get a good read of the data? I used a thread here! Enable a thread to read the data using a dead loop! Once you have the data, read it and put it in a stringlist for our use!
Good we step by step to achieve!
Let's start with the definition of a global variable. Create a new global variable page Mainunit.pas We declare two global variables first
The code is as follows
Unit Mainunit;interface
Uses CLASSES,SYNCOBJS;
Var
m_lock:tcriticalsection;//critical section, multithreading synchronization problem. Tcriticalsection
M_msglist:tstringlist;
Implementationend.
We then create these two objects in the window creation event of the main program.
Procedure Tform6.formcreate (Sender:tobject);
Begin
M_msglist:=tstringlist.create;
M_lock: =tcriticalsection.create;
End
Next we refer to this page in the program and Thread Code threads page Mythread.pas code as follows
Unit Mythread;interface
Uses classes,sysutils,forms,windows,variants,idiohandler,mainunit;
Type
Tmainthread = Class (TThread)
Private
Protected
Procedure Foo;
Procedure Execute;override;
Public
Constructor Create (Suspended:boolean);
End;implementation
Uses Client;
Constructor tmainthread.create (Suspended:boolean);//Create Thread
Begin
Inherited Create (Suspended);
Freeonterminate:=true;
End;procedure Tmainthread.foo;
Var
msg:string;
Bool:boolean;
Begin
Bool:=true;
while bool do begin
Try
Msg:= Form6.IdTCPClient1.IOHandler.ReadLn;
if (msg= ") Then
Bool:=false
Else
Begin
M_lock.enter;
M_msglist.add (MSG);
M_lock.leave;
End
Except
Bool:=false;
End
End
End
Procedure tmainthread.execute;//Thread Start
Begin
Foo;
End;
End.
What's the thread doing? We use threads in our programs! First of all, of course, to refer to the Mythread startup code in the program as follows Connection button event start thread at connection time
Procedure Tform6.conetclick (Sender:tobject);
Begin
Try
If not (idtcpclient1.connected) then
Begin
Idtcpclient1.connect;
Tmainthread.create (FALSE);
IdTCPClient1.IOHandler.writeln (' Lianjie ');
ShowMessage (' connection succeeded ');
End
Except
ShowMessage (' connection failed ');
End
End
The corresponding we send the read part also remove all the read all to the thread to deal with!
Procedure Tform6.sendclick (Sender:tobject);
Var
str:string;
Begin
Str:=edit1.text;
if (idtcpclient1.connected) then
IdTCPClient1.IOHandler.writeln (STR);
End
Here the thread reads everything we put into the stringlist because there may be unsafe access when we operate the interface! Because in the message sent over by the server, there may be some of the commands that you define to execute the commands that may directly manipulate some of the main window's events! While online thread is not safe to manipulate certain controls directly! So let's put all the data in the Stringlist first! If it's another 2, you can put it in list or ObjectList!
The next step is to read the data in the Stringlist and show it in Memo1! Here I use a timer to check the Stringlist! Add a timer to set the time to 1 milliseconds! We set the state of its activity in the Onconnected event of the TCP client control!
Enabled False
Interval 1
Procedure tform6.idtcpclient1connected (Sender:tobject);
Begin
Timer1.enabled:=true;
End
Stop activity Oh the event is placed in the Ondisconnected event of the TCP client control!
Procedure tform6.idtcpclient1disconnected (Sender:tobject);
Begin
Timer1.enabled:=false;
End
And then we do that in the event response function.
Procedure Tform6.timer1timer (Sender:tobject);
Var
msg:string;
Begin
M_lock.enter;
While M_msglist.count > 0 do
Begin
Msg:= ";
MSG: = M_msglist[0];
M_msglist.delete (0);
if (msg<> ") Then
MEMO1.LINES.ADD (MSG);
End
M_lock.leave;
End
Let's run it again and look at the effect! The effect is just the same as the basic! But the only difference is that! The client can accept data from the server at any one time! Instead of actively sending data, you can only get it single-time! And using the stringlist you can safely execute the corresponding event or function here! Does not have any effect on the operation of the thread accepting data!
Well here the client can actively send data to the server and can receive feedback from the server! But everybody noticed! If the server wants to actively send data to the client it seems that it is not possible! Because there is only one response in the Idtcpserver1execute event of the client that responds to its conversation on the server! To send data to this user!
Let's do a bit about how the server sends broadcast messages to all users!
Add a button to the server for the broadcast as well as a text input box!
In the button time our code is as follows
Procedure Tform6.button3click (Sender:tobject);
Var
Clist:tlist;
Count:integer;
str:string;
Begin
Str:=edit1.text;
Try
CList: = IdTCPServer1.Contexts.LockList;
For Count: = 0 to Clist.count-1 do
Begin
Tidcontext (Clist[count]). Connection.IOHandler.WriteLn (STR);
End
Finally
IdTCPServer1.Contexts.UnlockList; Be sure to unlock it or it will cause a deadlock.
End
End
All right, let's compile the client and open up a few more to test the results! How about the server can proactively send data to all connected users!           If it is in accordance with our previous client is not used at any time ready to receive then the server will not accept the broadcast data or the data received is not accurate! Use the Indy10 TCP connection tutorial (series three) in Delphi 2007 to do a service-side how to proactively send information to a customer!
First, the server to send a message to a user, then it means that no client must have a unique identity flag! such as user name User ID and so on! Here we will use the user name! We add a user name when connecting to the client to differentiate the user!
We add a text input box on the client named UserName in the connection button code as follows procedure Tform6.conetclick (Sender:tobject);
Var
str:string;
Begin
Str:=username.text;
If Str= ' Then
Begin
ShowMessage (' Please enter user name ');
Exit
End;try
If not (idtcpclient1.connected) then
Begin
Idtcpclient1.connect;
Tmainthread.create (FALSE);
IdTCPClient1.IOHandler.writeln (' @User: ' +str);
ShowMessage (' connection succeeded ');
End
Except
ShowMessage (' connection failed ');
End
End
Here we add "@User:" in front of the user name in order to differentiate the information sent to the server with other clients! You can define it yourself!
OK then let's go to the service-side code! In order to manage user data conveniently we first define a user class code and I'll post it directly!
Userobj.pas
-----------------------
Unit Userobj;interface
Uses
Classes,
SYNCOBJS,
Sysutils,
Idcontext;
Type
Tuserclass=class (TObject)
fusername:string; You can also define more data and methods
Fcontext:tidcontext; All that is to be defined here is the ability to send information within an object public
constructor create;
destructor Destroy; Override
Procedure checkmsg (Acontext:tidcontext); This is used for object class processing information published
Property username:string read Fusername write fusername;
End;implementation
Uses Server;
Constructor Tuserclass.create;
Begin
inherited;
Fusername:= ";
End;destructor Tuserclass.destroy;
Begin
inherited;
End;procedure tuserclass.checkmsg (Acontext:tidcontext);
Var
msg,key,value:string;
Len:longint;
Begin
Try
Fcontext: = Acontext;
AContext.Connection.IOHandler.CheckForDisconnect (True, true);
MSG:=ACONTEXT.CONNECTION.IOHANDLER.READLN ();
if (msg<> ") Then
Begin
if (msg[1]= ' @ ') then//@ represents the command
Begin
Len:=length (MSG);
if (len>6) then
Begin
Key:=copy (MSG, 2, 4); Command symbols
If key= ' User ' then
Begin
Value:=copy (MSG, 7); Value
Fusername:=value;
FORM6.MEMO1.LINES.ADD (' User: ' +fusername+ ' login server! ‘) ;
End
End
End
Else
Form6.Memo1.Lines.Add (fusername+ ': ' +msg);
End
Finally
End
End
End.------------------------------------------------------------------
Well, let's see how the server program uses this class to manage user data!
Let's refer to userobj and then do so on the connection event OnConnect of the IdTCPServer1 control!
Procedure Tform6.idtcpserver1connect (Acontext:tidcontext);
Begin
Acontext.data:=tuserclass.create;
End
Again, we're releasing this object when we're disconnected.
Procedure Tform6.idtcpserver1disconnect (Acontext:tidcontext);
Begin
AContext.Data.Free;
Acontext.data: = nil;
End
Then we have to send the server's monitoring events to our user object to deal with!
We rewrite the OnExecute event code of the IdTCPServer1 control to read as follows:
Procedure Tform6.idtcpserver1execute (Acontext:tidcontext);
Begin
Tuserclass (Acontext.data). Checkmsg (Acontext);
End
Do this here let's run a look at the effect! ~ After the client enters the user name and then clicks Connect multiple users to connect, we find that the information on the server can identify who sent it! Then do the server for a user to send messages!
We add a username text input box on the server to specify the sending information! The name is also UserName and then a single-User send button is added
Button events are as follows
Procedure Tform6.button4click (Sender:tobject);
Var
Clist:tlist;
Count:integer;
str,user:string;
Begin
Str:=edit1.text;
User:=username.text;
if (user= ") Then
Begin
ShowMessage (' Please enter the user name to specify the sending information! ‘);
Exit
End;try
CList: = IdTCPServer1.Contexts.LockList;
For Count: = 0 to Clist.count-1 do
Begin
if (Tuserclass (Tidcontext (Clist[count]). Data). Username=user) then//Convert to object and determine the user name of the object
Tidcontext (Clist[count]). Connection.IOHandler.WriteLn (STR);
End
Finally
IdTCPServer1.Contexts.UnlockList; Be sure to unlock it or it will cause a deadlock.
End
End
The finishing touches are to add a starter light effect to the server and a simple handshake to quit! Probably the reason is to send an exit to the server and then the server exits after the client exits! This is also done to safely exit the connection! If you do not do this step seems to have no big problem ~ in the test may have some hints that the connection has not ended before exiting the main program! This question I looked up some foreign documents ~ above said "This is the normal notice of Delphi!" Hint is not necessarily an error ~ ~ can choose to compile the time to ignore the message! ~ As long as the program in the independent operation without error on the line! ~
OK! ~ Let's test if we can actually specify the user to send the message!

Indy 10.5.8 for Delphi and Lazarus modified version (2011)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.