Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TCPSERVER Indy component 1

Status
Not open for further replies.

gp4

Technical User
Sep 27, 2002
30
AU
I need some help with using the INDY component TCPSERVER/TCPCLIENT in delphi 7.
To start off I'm trying to write text over a socket connection. So at the server end I have a line:

asender.thread.connection.writeln('test');


And at the client end:

data:=tcpclient1.readln();


But find that it will just hang.

Can anyone offer assistance.

Thanks
 
Hey there.

I won't post code sample here, I will just give you a clue :). The problem is (correct me if i am wrong) that you don't know when the server will send you anything and you just start to "ReadLn" from connection on client. If the client (in your case) starts ReadLN'ing first and the server sends text, then everything is okay, the app should "unfreeze" after the server had the text sent. Othervise your application will remain frozen until server sends the next package. You can solve the problem of "frozen" app by specifiyng the timeout for readLn operation, it should be something like this:
Code:
data:=tcpclient1.readln('', 10); // waiting 10 millisends for the package;
But that whould only read once from the socket. Going further... You need a timer and on each OnTimer event you'll be trying to read from the socket and if the server had sent anything then you'll read the data from client's recieve buffer, if hadn't then after specified timeout your app will continue to do what ever it was doing?

Hope that that makes any sense.

--- McMerfy
 
Hi McMerfy,
Thanks for your reply.
I'm using commandhandlers on the tcpserver component,
so I send a command from the client to the server then start to readln, and when the server receives the command, it will writeln.
Would this be an appropriate approach to take as this is where I find it will just hang.

Are you able to post/email a small sample code.

Thanks for your help
 
Hey gp4
Here's the smalest sample app to demonstrate how it supposed to work. In example give server ONLY sends data to client when it recieves anything from any client.
Create a new app and place on it1 TCPServer, 1 TCPClient, 1 Timer, 2 ListBox (1 LB to display messages rcvd by server, 1 LB to display messages rcvd by client), 2 TButton (1 button to connect/disconnect client and 1 buttong to send text). Here we go...
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin // connecting/disconnecting client
  with aClient do
  begin
    if Connected then
    begin
      Disconnect;
      Exit;
    end;
    Host := '127.0.0.1';
    Connect;
  end
end;

procedure TForm1.aServerConnect(AThread: TIdPeerThread);
begin
// event fired by server when client has connected
  ServerListBox.Items.Add('Client connected')
end;

procedure TForm1.aServerDisconnect(AThread: TIdPeerThread);
begin
// event fired by server when client has disconnected
  ServerListBox.Items.Add('Client disconnected')
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
// if client connected then sending text to server
  with aClient do
  begin
    if (not Connected) then Exit;
     WriteLn('Text to server');
  end;
end;

procedure TForm1.aServerExecute(AThread: TIdPeerThread);
var
  AText : String;
begin
// event fired by server when it recieves text from a client
  with AThread do
  begin
// reading text rcvd
    AText := Connection.ReadLn('', 10);
    if (AText <> '')then
    begin
// Displaying text rcvd
      ServerListBox.Items.Add(AText);
// Sending a response
      Connection.WriteLn('Response from server');
    end;
  end;
end;

procedure TForm1.aClientConnected(Sender: TObject);
begin
// Client has successfully connected
// Trying to readd from connection every N milliseconds
  Timer1.Enabled := True;
end;

procedure TForm1.aClientDisconnected(Sender: TObject);
begin
// Client has disconnected, no need to read anymore
  Timer1.Enabled := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  AText : String;
begin
// Client sie timer. trying to read every OnTimer event
  with aClient do
  begin
    AText := ReadLn('', 10);
    if (AText <> '')then begin
// text rcvd. Displaying it
      ClientListBox.Items.Add('Recieved ' + AText);
    end;
  end;
end;
Hope that helps.

--- McMerfy

 
Hi McMerfy,
Thanks for your update, it works well.
I was able to modify it and include it so that I can now use that principle within a TCPSERVER command handler.
Thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top