Write Network-Aware Applications with Delphi

Businesswoman using laptop in office
Morsa Images/Taxi/Getty Images

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;

Too 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.

p.s. For a more complex project, be sure to explore the Delphi\Demos\Internet\Chat project - a simple network chat application - it uses one form (project) for both the server and the client.