Delphi provides numerous
objects to allow you write applications that exchange data
over the network (Internet, intranet, local). In this article
we'll examine two Delphi components: TServerSocket and
TClientSocket, both designed to let you read and write
information over a TCP/IP connection.
On Winsock and Delphi socket components
Windows
Sockets or Winsock is an open interface for network
programming under Microsoft Windows. Winsock provides a set of
functions, data structures...etc required to access the
network services of any protocol stacks. Winsock acts as a
link between network applications and underlying protocol
stacks.
Delphi socket components (wrappers for the WinSock) let you
create an application that can communicate with other systems
using TCP/IP and related protocols. Using sockets, you can
read and write over connections to other machines without
worrying about the details of the underlying networking
software.
The Internet palette on the Delphi components
toolbar hosts the TServerSocket and TClientSocket as well as
TcpClient, TcpServer and TUdpSocket components.
How to reach a particular service on a specific
network
One simplest answer is that the client has to
be allowed to send messages to that service and read replies
from it. The most practical way of doing a network send/read
is to use sockets.
On Ports and Hosts
In order to start a socket
connection, using the socket component, a host and a port have
to be specified. In general, host specifies an alias for the
IP address of the server system; port specifies the ID number
that identifies the server socket connection.
A simple
one-way-send-text program
Let's see how to build a
simple example using the Socket components provided by Delphi.
We'll create two forms, one for the server and one for the
client computer. The idea is to enable the clients to send
some textual data to the server.
To start, fire up Delphi twice, one project for the server
application and one for the client.
The server side of the story
On a form drop one TServerSocket
component, and one TMemo component. Let it look like:
In the OnCreate event for the form add the next code:
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Port := 23;
ServerSocket1.Active := True;
end;
|
Next, the OnClose should look like:
procedure TForm1.FormClose
(Sender: TObject; var Action: TCloseAction);
begin
ServerSocket1.Active := false;
end;
|
The client side of the story
For the client application, add a
TClientSocket, a TEdit and a TButton components to a form. It
could look something like: And, here's all the code you need
on the client:
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1.Port := 23;
//local TCP/IP address of the server
ClientSocket1.Host := '192.168.167.12';
ClientSocket1.Active := true;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientSocket1.Active := false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if ClientSocket1.Active then
ClientSocket1.Socket.SendText(Edit1.Text);
end;
|
The code pretty much describes itself: when a client clicks
a button, the text specified inside the Edit1 component will
be send to the server with specified port and host address.
Back to server!
The final touch in this sample is
to provide a function for the server to "see" the data the
client is sending. The event we are interested in is
OnClientRead - occurs when the server socket should read
information from a client socket.
This is the code:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(Socket.ReceiveText);
end;
|
To easy? Well no of course not - it works! But, what if you
have more than one client sending data to the server? In such
situations you'll need a little more to code:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer;
sRec : string;
begin
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
begin
with ServerSocket1.Socket.Connections[i] do
begin
sRec := ReceiveText;
if sRecr <> '' then
begin
Memo1.Lines.Add(RemoteAddress + ' sends :') ;
Memo1.Lines.Add(sRecr);
end;
end;
end;
end;
|
That's all. When the server reads information from a client
socket it adds that text to the Memo component, both the text
and the client RemoteAddress are added. See it in action