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 (27)


Using The TServerSocket ComponentGo to Brian Pedersen's websiteFormat this article printer-friendly!Bookmark function is only available for registered users!
Implementing a multithreaded server
Product:
Delphi 3.x (or higher)
Category:
Internet / Web
Skill Level:
Scoring:
Last Update:
10/20/2000
Search Keys:
delphi delphi3000 article borland vcl code-snippet TServerSocket multithreading socket sockets
Times Scored:
30
Visits:
28947
Uploader: Brian Pedersen
Company: Pentia A/S
Reference: Caos Development
 
Question/Problem/Abstract:
The Delphi documentation on the TServerSocket's multithreading capabilities can appear a little sparse for the untrained eye. I will try and shed a little more light on the subject.
Answer:



Actually it's pretty easy to make a multithreaded server that listens for messages on a socket. Delphi has a component for that: the TServerSocket.

But you need a little bit of knowledge to use it.

In order to structure your work, you should:

- Add a TServerSocket to your main form.
- Set the Servertype property to stThreadBlocking
- Create a new unit (shown below) containing the server thread.


Make the following code on the OnSocketGetThread

procedure TfrmMain.fSocketGetThread(Sender: TObject;
  ClientSocket: TServerClientWinSocket;
  var SocketThread: TServerClientThread);
begin
  // This creates the TServerThread object I have shown
  // in the code below. A new object is created each time
  // A new connection is established.
  SocketThread := TServerThread.Create( FALSE, ClientSocket );
end;

The TServerThread is an object I have created myself. The object inheits from TServerClientThread and contains the code that actually are reading and writing from the socket.

The unit I created contains at least the following code:

unit serverthread;

interface

uses
  windows, scktcomp, SysUtils, Classes, Forms;

type
  EServerThread = class( Exception );
  // The serverthread is a descendant of the
  // TServerClientThread
  TServerThread = class( TServerClientThread )
    private
      fSocketStream : TWinSocketStream;
    public
      procedure ClientExecute; override;
      // The ClientExecute overrides the
      // TServerClientThread.ClientExecute
      // and contains the actual code that is
      // executed when the thread is started
  end;

implementation

procedure TServerThread.ClientExecute;
begin
  inherited FreeOnTerminate := TRUE;
  try
    fSocketStream := TWinSocketStream.Create( ClientSocket,
                                              100000 );
    // 100000 is the timeout in miliseconds.
    try
      while ( not Terminated ) and ( ClientSocket.Connected ) do
      try
        // This is where you will do the actual
        // Waiting for input, Reading and writing
        // The examples below shows what you can
        // put in here.
      except on e:exception do
        begin
          // An error has occurred, close and exit
          ClientSocket.Close;
          Terminate;
        end;
      end;
    finally
      fSocketStream.Free;
    end;
  except on e:exception do
    begin
      // An error has occurred, close and exit
      ClientSocket.Close;
      Terminate;
    end;
  end;
end;

When the connection is established, the thread needs to wait for incoming data. You can use this code to wait for data:

if ( not Terminated ) and
   ( not fSocketStream.WaitForData( 1000000 ) ) then
begin
  // Handle the timeout
end;
// There are incoming data on the socket!

To read data, you should have a buffer to store the data in. Usually the buffer is a PByteArray or a array of chars. In this example I have a buffer called fRequest which is a array of chars. Furthermore I am expecting a fixed number of bytes. My array has the size of the constant REQUESTSIZE.

var
  ac, readlen : integer;
begin
  FillChar( fRequest, REQUESTSIZE, 0 );
  ac := 0;
  repeat
    readlen := fSocketStream.Read( fRequest[ac],
                                   1024 );
    // I read in chunks of 1024 bytes until the buffer
    // is full
    ac := ac+readlen;
  until ( readlen = 0 ) or ( ac = REQUESTSIZE );
end;

If readlen is 0 then I do not receive any more data. The Read function times out after 100000 miliseconds as stated in the TWinSocketStream.Create(). If you do not know how much data to expect, you should set this timeout fairly small. 30 seconds should be a maximum in most situations.

When sending a reply, you should be aware of your clients behavior. Many clients only waits for one package of reply, others expects many packages.
In this example, I have a client that only expects one package, so I have to send my data back in one chunk:

fSocketStream.WriteBuffer( fRep, fReplySize );

The fRep is the reply buffer, and fReplySize is the size of the replybuffer.





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Gettin junk data along with required data
    siva (Aug 29 2005 10:14AM)

while reading socket data using receivebuf method. I find lot of junk along with original data after copied to textfile. Please give some idea to block the junk values.

Regards,
siva
Respond

Socket not accept client
    pichai (Aug 4 2005 11:55AM)

i have a problem  
when i use TServerSocket  and Create ClientExecute.  Program can good work. but it can run about 2 hours then Client can't Connect to my program (client thread it will terminate with time out). I don't know Why Socket not Accept Client or Why client can't connect to server. (remark my program test with 100 connections of Client)
Respond

Getting the ScktComp unit TServerSocket for Delphi 7
    Aaron Riley (Feb 25 2005 2:38PM)

I have the "regular" version of Delphi 7 and it does not have the Service Application component to use ServerSocket. Does anyone know where I can get this?
Respond

RE: Getting the ScktComp unit TServerSocket for Delphi 7
ganesh goody (Oct 26 2005 8:54AM)

hi
  just go for component install packages
click the Add button select C:\Program Files\Borland\Delphi7\Bin\dclsockets70.bpl thats it

Respond

jýl
    huseyin ozdemir (Mar 18 2004 5:39PM)

dfgdfgdfgdfgdfgdfgdfgfdgdfgdfgdf
Respond

would you please give me the source code?
    caocih (Feb 18 2001 10:11AM)

I have problems,the server can not send message to client,
would you please give me the source code?
Include server and client,use Blocking type.thanks.
Respond

RE: would you please give me the source code?
Rudy Lay (Jun 23 2001 2:21PM)

  I got into the same problem with you, so far I can only establish the connection and recieving partial of the data from client, and never succesfully closing the conection. Are there any body who would give me some simple example program source code, that give example how to send and recieve massages both client and the server side and how to close the connection and ending the thread? I would appreciated alot

Thanks in advance
  Rudy L.

Respond

RE: RE: would you please give me the source code?
Arnold (Jul 14 2001 7:44AM)

I think there's a demo program that ships with delphi, you can check it out, it's pretty cool, nice and simple.
Respond

RE: RE: RE: would you please give me the source code?
Vaidas Gaidelis (Jul 16 2002 12:18PM)

Yes, it's simple, but doeasn't show how to support multiclient. Server sends only to socket(0). Maybe someone made with multiclient, cause, now i'm writinh http server...
Respond

RE: RE: would you please give me the source code?
a a (Mar 2 2005 3:50PM)

you are stupid :)) because you can't use google.com
Respond

How to end Thread when client Disconnect?
    William Douglas Knak Filho (Jan 19 2001 11:21AM)

I trying to end thread when clien disconnects... the thread is created when the client connects, but I maintaining the thread active until de client disconnet... how to can I make this? Thanks...
Respond

RE: How to end Thread when client Disconnect?
William (Jan 31 2001 12:16PM)

forget... (please enter a valid coment)
Respond

Sending File using Sockets
    Ian Groves (Dec 26 2000 7:12AM)

How do i send/receive/AND SAVE files using Sockets, i can do it with Text files but not Data files e.g BMP/GIF/EXE


Thanks in advance
Respond

RE: Sending File using Sockets
teleme (Apr 14 2003 5:34AM)

I used to send file on stand Winsocket function ,you should design all the thread work by hand,then handle all the package on you own function.
Respond

RE: RE: Sending File using Sockets
hamid (Aug 10 2004 9:43PM)

Please help me to do this work !!!
Respond

Trap sockets
    VRK (Dec 4 2000 12:20AM)

Hi,
I would like to Trap all the socket events that occure in my/other
mechine. Can I do some programme that Traps all socekts' and its
events ? If so that will help me for my MIS related work.

regards
VRK
Respond

sending images & bin-values
    venki (Dec 4 2000 12:03AM)

Hi,
I try to send Bmp,Gif files as a stream and the read event gets called 2 or more times( but i send only once ).When i receive 1st time the received length is same as I sent. But why, gets called more than once. Since that I get stream error.

Thanx
venki

Respond

RE: sending images & bin-values
teleme (Apr 14 2003 5:37AM)

I begin this work recent day,You should design a thread on socket ,its function is read an send stream,you can find some tip on delphi's help
  sdk/winsocket ,some key word like "recv,send,select,listen,connect"ext
Respond

Binding IP
    Oudi Jakaria (Nov 16 2000 2:24AM)

Hi
I am using multiple network card in my PC, but I have problem
to binding TServerSocket to one IP manualy from textbox. The
error message is "Cannot assign to Read-Only Property".

The syntax that i used is like :

procedure TForm1.Button1Click(Sender: TObject);
begin
   TServerSocket.Active := False;
   TServerSocket.Socket.LocalAddress := Textbox1.text;
   TServerSocket.Socket.LocalPort := StrToInt(Textbox2.text);
end;

Any suggestion ?

And how to create Multiple connection with TServerSocket and
TClientSocket in Delphi 5 Enterprise ?

Thanks
Respond

RE: Binding IP
Brian Pedersen (Nov 16 2000 2:35AM)

One of the biggest problems with TServerSocket is that it can only bind to one network card, and onyl to the first in the list.
There are no immediate solution to this other than write a new component inheriting from TServerSocket that has a feature to select network card.

I have had experiences with applications where I had to switch the network card in the PC (physically place them in different sockets) before I had the chance of using the right card.
Respond

TServerSocket w/o SocketStream
    Vlad Semjonov (Nov 14 2000 1:25PM)

  In description for TServerSocket(TCustomServerSocket) OnClientRead event as alternative to TWinSocketStream implementation also mentioned method of writing thread-safe event handler based on Socket parameter. I didn't saw any OnClientConnect, OnClientRead, OnClientWrite, OnClientDisconnect events lunched in stThreadBlocking mode ? I force those events to fire up after recompiling scktcomp.dcu with small changes , but what about original design since 1997 ?

Rgds,
Vlad.

P.S. Changes I made in scktcomp.pas :

procedure TServerClientThread.DoRead;
begin
{ClientSocket.ServerWinSocket.Event(ClientSocket, seRead);}
Event(seRead); {added}
end;

procedure TServerClientThread.DoWrite;
begin
{FServerSocket.Event(ClientSocket, seWrite);}
Event(seWrite); {added}
end;

procedure TServerClientThread.ClientExecute;
var
  FDSet: TFDSet;
  TimeVal: TTimeVal;
begin
Event(seConnect);{added}
...
...
Event(seDisconnect);{added}
end;

Respond

Problem with TClientSocket...
    S S B Magesh Puvananthiran (Nov 6 2000 1:13PM)

I'm using a TClientSocket in my application. But i'm not able to send data thru' the socket in the form's OnShow event. But when i try to send the same data in a button's click event .. i'm able to send... what could be the problem? could you please explain... on this...The server is a Java server... i'm sending data to a Java server running on a particular port... how can i use this TClientSocket component effectively against a java server?

Thanx in advance.
Magesh.
Respond

RE: Problem with TClientSocket...
HTK (Nov 7 2000 8:17PM)

maybe your socket isn't connected yet, try to tell him to connect on the onshow but make him send on the onconnect event of the clientsocket
anyway, if you need further help, send me the source and i'll take a look at it

regards
HTK
Respond

RE: RE: Problem with TClientSocket...
S S B Magesh Puvananthiran (Nov 8 2000 7:50PM)

Let me give you the code out here. Have a look at it.
You can refer the Chat application in Delphi Demos.
In the form's on show event : I wrote the following:

ClientSocket1.Address := IP address of the machine
ClientSocket1.Port := Port number
ClientSocket1.Active := True;

After this , i was trying to send some data to that machine with the following code:

ClientSocket1.Socket.SendText('some text');

The 'some text' is not reaching that machine.

While debugging the application i'm seeing that the connection is active with the machine i.e Active is True;

I wrote the error handling also; I'm not getting either connect or send error;

Not only this. If you put the same code in one event(any event i tested with OnShow and OnClick event, may be i'm wrong) i.e connecting to the machine and sending data , you can see the problem i'm telling.

Please Test it and let me know .

Thanx.
Magesh.
Respond

RE: RE: RE: Problem with TClientSocket...
HTK (Nov 10 2000 9:16AM)

I tryied:

ClientSocket1.Port:=1000;
clientsocket1.host:='200.197.136.47';
clientsocket1.Active:=true;
clientsocket1.Socket.SendText('wha');

on the onshow and really does not work but if you do

ClientSocket1.Port:=1000;
clientsocket1.host:='200.197.136.47';
clientsocket1.Active:=true;

and the on the onconnect of the socket put
clientsocket1.Socket.SendText('wha');
then  it works here, tell me by e-mail if you're having any problems yet
htk@carrier.com.br
Respond

RE: RE: RE: RE: Problem with TClientSocket...
S S B Magesh Puvananthiran (Nov 10 2000 12:07PM)

Thanx a lot for your help even though i solved the problem myself yesterday with the whole day spent only for that. I did send a mail to you just now.

Thanx.
Magesh.
Respond

RE: Problem with TClientSocket...
ZF (Nov 11 2000 12:11AM)

I meet the same problem with you, but I found that if you set TClientSocket.Port with the server's computer name and TClientSocket.Address with the server's computer IP, you will connect succeed and quickly!
But I read then Delphi's help I found that the help is not agree to this, it think the TClientSocket.Port :=(( Your computer 's IP ) will connect quick, but I use it found that client send message can't reach the server quickly and reliably).

Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


   


  Community Ad of
D. Wischnewski
 
   














 







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