Making an application a TCP/IP Client(with sample code)...

Connecting to a TCP/IP server from a Delphi Client

This article is a continuation of my previous article(http://www.howtodothings.com/showarticle.asp?article=218)

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 (http://www.delphi3000.com/article.asp?id=1695), 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;



Enjoy!!!



Thanks.

Magesh.

 

Share this article!

Follow us!

Find more helpful articles: