delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback



Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi








Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (6)


Making an application a TCP/IP Client (with sample code)...Format this article printer-friendly!Bookmark function is only available for registered users!
Some Sample Code...
Product:
Delphi 4.x (or higher)
Category:
Communication
Skill Level:
Scoring:
Last Update:
03/14/2002
Search Keys:
delphi delphi3000 article borland vcl code-snippet TClientSocket,Communication,Sockets,TCP/IP,Ports
Times Scored:
20
Visits:
17352
Uploader: S S B Magesh Puvananthiran
Company:
Reference: N/A
 
Question/Problem/Abstract:
Connecting to a TCP/IP server from a Delphi Client
Answer:



This article is a continuation of my previous article
Making an application a TCP/IP Client intended to demonstrate how we can use the TclientSocket component in Delphi as a TCP/IP client against any TCP/IP server. The server could be written in Delphi using TserverSocket component or any piece of code that acts as a TCP/IP server. In my case, I’m interacting with a Java code acts as a TCP/IP server.

In my project, I’m just sending a bunch of bytes to that Java server and the Java server reads the bytes and doing some tasks sending a different bunch of bytes as response to the Delphi Client.

In my last article (Making an application a TCP/IP Client), I explained the problem I faced and a solution I found for that.

In this article, let me give some sample code I used in that project since some people asked me to send the source code for this socket communication by sending separate e-mails. I appreciate them for their interest. Here U Go!! Enjoy!!!

My project uses nearly nine forms and all the forms need to interact with the Java server at least once. So I added a DataModule and put a TClientSocket Component there:

The following is the code for that:

unit DataMod;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ScktComp, OleServer;

type
  TdmDataModule = class(TDataModule)
    csClientSocket: TClientSocket;
    procedure csClientSocketError(Sender: TObject;  Socket: TCustomWinSocket; ErrorEvent:   TErrorEvent;   var ErrorCode: Integer);
    procedure csClientSocketRead(Sender: TObject;
    Socket: TCustomWinSocket);
procedure DataModuleDestroy(Sender: TObject);
  private
    { Private declarations }
  pub
lic
    FWaiting : boolean;
    { Public declarations }
  end;

var
  dmDataModule: TdmDataModule;

implementation

{$R *.DFM}

procedure TdmDataModule.csClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
//Reading data back from server thro socket
var
  Buffer : array [0..4095] of char;
  BytesReceived : integer;
  MemoryStream : TMemoryStream;
begin
  while FWaiting do
  begin
    MemoryStream := TMemoryStream.Create;
    try
    //This time delay depends on the network traffic and also you can put the time delay between reads
    //I've just put some 200 milliseconds for my application before it starts reading from the server.
    Sleep(200);
      while True do
      begin
        BytesReceived := Socket.ReceiveBuf(Buffer,SizeOf(Buffer));
        if (BytesReceived <= 0)  then        
          Break
        else
        begin
          MemoryStream.Write(Buffer,BytesReceived);
        end;
      end;

      FWaiting := False;

      MemoryStream.Position := 0;

     //XMLResponse is a global stringlist i'm using in my application to convert the bytes received into string
     //You can use other ways to get the contents of a memorystream
     XMLResponse.LoadFromStream(MemoryStream);
    finally
      MemoryStream.Free;
    end;
  end;
end;

procedure TdmDataModule.csClientSocketError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
{Whenever you get a specific type of error while running the client you will be given a messagedlg showing that the error has occured; at that time you have to check whether the server is running correctly or not and if needed make the server run properly and then say OK.
Then csClientSocket.Open will try to reconnect to the server. So at this time if some transaction is in the middle you have to send the same stuff again after reconnecting.}
begin
  case ErrorEvent of
    eeGeneral :
    begin
      if MessageDlg('Error Connecting to Java server! ' + #13 + 'Check the server status and try again!!', mtInformation,[mbOk],0) = mrOk then
        csClientSocket.Open
    end;
    eeConnect :
    begin
      if MessageDlg('Error Connecting to Java server? ' + #13 + 'Check the server status and try again!!', mtInformation,[mbOk],0) = mrOk then
        csClientSocket.Open
    end;
    eeSend    :
    begin
      if MessageDlg('Error Connecting to Java server? ' + #13 + 'Check the server status and try again!!', mtInformation,[mbOk],0) = mrOk then
        csClientSocket.Open
    end;
    eeReceive :
    begin
      if MessageDlg('Error Connecting to Java server? ' + #13 + 'Check the server status and try again!!', mtInformation,[mbOk],0) = mrOk then
        csClientSocket.Open
    end;
    eeAccept  :
    begin
      if MessageDlg('Error Connecting to Java server? ' + #13 + 'Check the server status and try again!!', mtInformation,[mbOk],0) = mrOk then
        csClientSocket.Open
    end;
  end;
end;

procedure TdmDataModule.DataModuleDestroy(Sender: TObject);
begin
  //Closing the socket connection
  csClientSocket.Close;
end;

end.

Once you are done with the datamodule, you can include this datamodule in units wherever you need to interact with the server thereby you can avoid writing code to read data back from the server in various places of the project.

You can set the Host/Address and Port Number of the server to communicate at runtime through the runtime parameters.(I assume Delphi people aware of that runtime parameters)

Then in the project's main form's formcreate event; write the following code to connect to the server. i.e setting the IP address and Port Number of the server in the TClientSocket component and set Active to true.

//Connecting to the Java server on a particular port
  try
    with dmDataModule.csClientSocket do
    begin
      if Active then Active := False;
      
      //Getting the Address or Host Name of the server through the runtime parameters
      Host := ParamStr(1);
      //Getting the Port Number of the server at which the server listens through the runtime parameters
      Port := StrToInt(ParamStr(2));
      //Making the connection active
      Active := True;
    end;
  except on ESocketError do
    begin
      MessageDlg('Unable to Connect to Java Server ' + #13 + 'Please Try Again!',mtInformation,[mbOk],0);
      exit;
    end;
  end;


Once you are connected to the server, you can use either the TClientSocket's sendtext or sendstream method to send the data to the server.

for example:

procedure Send;
begin
    //Checking whether the socket connection is ready or not
   //If not , the error handling part of the TClientSocket will be activated
    if csClientSocket.Active then
    begin
         //Sending the text through the socket connection
        csClientSocket.Socket.SendText('The string to send');

        //Setting a flag to wait until the server sends the response back         
        dmDataModule.FWaiting := True;
        while dmDataModule.FWaiting then
             Application.ProcessMessages;
    end;
end;





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
DLL?
    Euan Jonker (Feb 22 2001 7:10AM)

The article is all fine, but what if you have this communication in a DLL?
In a DLL, you don't have events, how does one go about to receive the data without the OnRead event?
I have been struggling with this one, but worked around the problem...sort of, but can anyone maybe help me here?

Much appreciated,

Euan B. Jonker

Sofware Developer
Stellenbosch
South Africa
Respond

RE: DLL?
S S B Magesh Puvananthiran (Feb 27 2001 10:44AM)

Thank you for writing.
I never tried the same with a Dll. But there should be some way of doing that as you said. I think you may need to use some Win APIs to do that. I'm not sure yet. I came up with this article because of my current project. In my project, I needed to send some bunch of XML stuff to another machine from Delphi and get the response back from that machine and parse it and do the needed things. This forced me to use the TClientSocket component in Delphi. Because it is part of my application i developed using Delphi. I'll try the option like putting the communication in a DLL sometime later since i'm really busy with my project now.

Anyhow, thanx again for writing in.
But why dont you share the solution you found whether it is a right one or not?

Magesh.

Respond

RE: RE: DLL?
Euan Jonker (Feb 28 2001 3:55AM)

Well, I just put the whole thing in a loop, sleeping inbetween checks to see whether the data has arrived by checking it's length being more than -1.   If data was returned, but is actually zero in length, it will return 0, but if no data was returned, it will return -1.

The kak now is, that I can't get ALL the data back, I only get 2/3 of it all, at first, I only got 1/3 back.

Since then, I have started playing around with NMStrm and NMStrmServ.
It works just great, I can send and recieve as much as I want.
But like with all good thing, there's kak aswell, I can't use this without events, so I'm back to square one!!!

If there is anyone out there that can send and recieve data over sockets, using streams, in a DLL, PLEASE HELP!!!!!!!!
Respond

RE: RE: RE: DLL?
Stefan Lechner (Jun 20 2001 5:58AM)

Hi,

your problem is that your sender is to fast. WinSock's may loose data if there are buffer overruns. Implement a simple hadshake between the client and the server.

Server sends one Datablock to the client.
Client receives the block and send a Ack to the server

and so on until the transmission is completed.


Respond

UDP
    RON (Jan 10 2001 12:42PM)

Hi there. This is a nice article on TCP/IP. Do you know anything about UDP? Perhaps you should do an article on that and it would be well appreciated.

Things like what happens if you keep sending someone UDPs.

Thanks.
Respond

RE: UDP
S S B Magesh Puvananthiran (Jan 19 2001 12:28PM)

Thank you for your comment.
I'm thinking of doing an article on UDP; but since i'm bit busy with my project, i couldn't concentrate on this. I'll do it whenever i find time. Atleast i'll give you an overview of how to do that in Delphi soon.

Thanx.
Magesh.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


   


  Community Ad of
L. Rosenstein
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)