?
Solved

What type of comunication should I use?

Posted on 2006-04-15
7
Medium Priority
?
305 Views
Last Modified: 2010-04-05
I have a program client that I distribute on the internet. The program with the server is located on a dedicated server.
What type of component/connection should I use in Delphi(7 or 2005 or 2006) to comunicate between client and server in order to have 100% uptime and 100% no connection problem.

I have triied Indy 10 IdTCpCClient and IdTCPServer but the server every day is down and some clients can't connect to it.

0
Comment
Question by:diandr
5 Comments
 

Author Comment

by:diandr
ID: 16459596
I would be grateful for a sample of client and sever with 2-3 commands.
0
 

Author Comment

by:diandr
ID: 16459658
The client program just sends commands and receive answers from the server. With indy there was a problem like closing connection before the client actually closed the application.
0
 
LVL 1

Expert Comment

by:nou68
ID: 16465385
what can of server you are building, is it satefull or statless ? ,
you can use also web services
0
 
LVL 5

Accepted Solution

by:
Scay7 earned 2000 total points
ID: 16465680
Wow same problem that i had ...

Okay i went through alot of ideas from searching the internet and downloading lots of SOCKET examples, INDY funny enough i had the most problems with *touch wood* but im not saying that INDY is stupid *far from it*. For a basic program to send commands and for the server to receive them i suggest a example that TheRealLoki made for me :

0. Below is a nice example of a server/client socket connect/disconnect example, very editable which i have done to do
    the things that i needed to make a client/server program. Thanks TheRealLoki

1. first off make sure that you have installed dclsockets70.bpl which comes standard with D7 Enterprise
2. I have D7 Enterprise and that bpl was there but not installed, so you might have to, just go to ->
          a. component
          b. install packages
          c. click ADD
          d. goto BIN directory in the root of delphi usually (c:\program files\borland\delphi7\bin)
          e. search for dclsockets70.bpl, click on it, and click OPEN
          f. It should have added "Borland Sockets Components" to make sure click on the components button
             and a TClientSocket & TServerSocket should be there

3. make a new application place a button on it and save the whole thing somewhere...
4. the *.pas file ->
//##########################################################
unit unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ScktComp;
(* demo by }-=Loki=-{ lokiwashere@yahoo.co.nz *)
type
  TForm1 = class(TForm)
    mLog: TMemo;
    ClientSocket1: TClientSocket;
    gbServer: TGroupBox;
    rbServer: TRadioButton;
    ServerSocket1: TServerSocket;
    eServerPort: TEdit;
    Label1: TLabel;
    bListen: TButton;
    eServerSend: TEdit;
    bServerSendToAll: TButton;
    gbClient: TGroupBox;
    Label2: TLabel;
    eClientPort: TEdit;
    bConnect: TButton;
    eClientSend: TEdit;
    bClientSend: TButton;
    rbClient: TRadioButton;
    Label3: TLabel;
    eAddress: TEdit;
    bOffline: TButton;
    bDisconnect: TButton;
    procedure bListenClick(Sender: TObject);
    procedure bServerSendToAllClick(Sender: TObject);
    procedure rbServerClick(Sender: TObject);
    procedure rbClientClick(Sender: TObject);
    procedure bConnectClick(Sender: TObject);
    procedure bClientSendClick(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure bOfflineClick(Sender: TObject);
    procedure bDisconnectClick(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Connecting(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

IMPLEMENTATION

{$R *.DFM}

procedure TForm1.rbServerClick(Sender: TObject);
    begin
        gbServer.Enabled := True;
        gbClient.Enabled := False;
    end;

procedure TForm1.rbClientClick(Sender: TObject);
    begin
        gbServer.Enabled := False;
        gbClient.Enabled := True;
    end;


// ********************************     server code here
procedure TForm1.bListenClick(Sender: TObject);
    begin
        ServerSocket1.Port := StrToIntDef(eServerPort.Text, 2000);
        ServerSocket1.Active := True;
    end;

procedure TForm1.bOfflineClick(Sender: TObject);
    begin
        ServerSocket1.Active := True;
    end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add('connection from ' + Socket.RemoteAddress);
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add('disconnection from ' + Socket.RemoteAddress);
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add(Socket.ReceiveText);
    end;

procedure TForm1.bServerSendToAllClick(Sender: TObject);
    var
        i: integer;
    begin
        for i := 0 to pred(ServerSocket1.Socket.ActiveConnections) do
         ServerSocket1.Socket.Connections[i].SendText(eServerSend.Text);
    end;

// ********************************     client code here
procedure TForm1.bConnectClick(Sender: TObject);
    begin
        ClientSocket1.Address := eAddress.Text;
        ClientSocket1.Port := StrToIntDef(eClientPort.Text, 2000);
        ClientSocket1.Open;
    end;

procedure TForm1.bClientSendClick(Sender: TObject);
    begin
        ClientSocket1.Socket.SendText(eClientSend.Text);
    end;

procedure TForm1.bDisconnectClick(Sender: TObject);
    begin
        ClientSocket1.Close;
    end;

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add(Socket.ReceiveText);
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

procedure TForm1.ClientSocket1Connecting(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add('connecting to ' + ClientSocket1.Address + ':' + IntToStr(ClientSocket1.Port));
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add('connected to ' + ClientSocket1.Address + ':' + IntToStr(ClientSocket1.Port));
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        mLog.lines.add('disconnected from ' + ClientSocket1.Address + ':' + IntToStr(ClientSocket1.Port));
        mLog.Perform(EM_SCROLL,SB_LINEDOWN,0);
    end;

end.
//##########################################################



5. the *.dfm file ->
//##########################################################
object Form1: TForm1
  Left = 345
  Top = 300
  BorderStyle = bsSingle
  Caption = 'Client and Server TEST Scay7(edited) Example TheRealLoki'
  ClientHeight = 323
  ClientWidth = 641
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  Position = poDefault
  PixelsPerInch = 96
  TextHeight = 13
  object mLog: TMemo
    Left = 372
    Top = 48
    Width = 261
    Height = 265
    TabOrder = 0
  end
  object gbServer: TGroupBox
    Left = 16
    Top = 40
    Width = 337
    Height = 105
    Caption = 'Server'
    TabOrder = 1
    object Label1: TLabel
      Left = 16
      Top = 28
      Width = 19
      Height = 13
      Caption = 'Port'
    end
    object eServerPort: TEdit
      Left = 72
      Top = 24
      Width = 41
      Height = 21
      TabOrder = 0
      Text = '2000'
    end
    object bListen: TButton
      Left = 224
      Top = 16
      Width = 75
      Height = 25
      Caption = 'Listen'
      TabOrder = 1
      OnClick = bListenClick
    end
    object eServerSend: TEdit
      Left = 8
      Top = 72
      Width = 193
      Height = 21
      TabOrder = 2
      Text = 'Text to send from server'
    end
    object bServerSendToAll: TButton
      Left = 224
      Top = 72
      Width = 75
      Height = 25
      Caption = 'Send to all'
      TabOrder = 3
      OnClick = bServerSendToAllClick
    end
    object bOffline: TButton
      Left = 224
      Top = 40
      Width = 75
      Height = 25
      Caption = 'Offline'
      TabOrder = 4
      OnClick = bOfflineClick
    end
  end
  object rbServer: TRadioButton
    Left = 16
    Top = 8
    Width = 113
    Height = 17
    Caption = 'Server'
    TabOrder = 2
    OnClick = rbServerClick
  end
  object gbClient: TGroupBox
    Left = 16
    Top = 176
    Width = 337
    Height = 137
    Caption = 'Client'
    TabOrder = 3
    object Label2: TLabel
      Left = 16
      Top = 44
      Width = 19
      Height = 13
      Caption = 'Port'
    end
    object Label3: TLabel
      Left = 16
      Top = 20
      Width = 38
      Height = 13
      Caption = 'Address'
    end
    object eClientPort: TEdit
      Left = 72
      Top = 40
      Width = 41
      Height = 21
      TabOrder = 1
      Text = '2000'
    end
    object bConnect: TButton
      Left = 224
      Top = 16
      Width = 75
      Height = 25
      Caption = 'Connect'
      TabOrder = 2
      OnClick = bConnectClick
    end
    object eClientSend: TEdit
      Left = 8
      Top = 88
      Width = 193
      Height = 21
      TabOrder = 3
      Text = 'Text to send from server'
    end
    object bClientSend: TButton
      Left = 224
      Top = 88
      Width = 75
      Height = 25
      Caption = 'Send'
      TabOrder = 4
      OnClick = bClientSendClick
    end
    object eAddress: TEdit
      Left = 72
      Top = 16
      Width = 113
      Height = 21
      TabOrder = 0
      Text = '127.0.0.1'
    end
    object bDisconnect: TButton
      Left = 224
      Top = 40
      Width = 75
      Height = 25
      Caption = 'Disconnect'
      TabOrder = 5
      OnClick = bDisconnectClick
    end
  end
  object rbClient: TRadioButton
    Left = 16
    Top = 152
    Width = 113
    Height = 17
    Caption = 'Client'
    Checked = True
    TabOrder = 4
    TabStop = True
    OnClick = rbClientClick
  end
  object ClientSocket1: TClientSocket
    Active = False
    ClientType = ctNonBlocking
    Host = 'localhost'
    Port = 2000
    OnConnecting = ClientSocket1Connecting
    OnConnect = ClientSocket1Connect
    OnDisconnect = ClientSocket1Disconnect
    OnRead = ClientSocket1Read
    Left = 356
    Top = 164
  end
  object ServerSocket1: TServerSocket
    Active = False
    Port = 2000
    ServerType = stNonBlocking
    OnClientConnect = ServerSocket1ClientConnect
    OnClientDisconnect = ServerSocket1ClientDisconnect
    OnClientRead = ServerSocket1ClientRead
    Left = 360
    Top = 88
  end
end
//##########################################################

6. click on radiobutton for the server
   now click on the listen button for the server
   then click radiobutton for client
   and click the button for connect
   rest should be easy to figure out...

Peace Scay7
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16486231
I've changed the server demo on Scay7's question so that you can send the server several commands, and it will respond.
e.g send the command "DATE", and the server returns the current date,
feel free to take a look if you like
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21810377.html
It's using the standard sockets, not indy or ICS
Indy 10 has a "Command Handler" way of doing the same thing, or you can do that bit yourself with WriteLn/ReadLn and "IF" statements.
Strangely, Version 9 was pretty stable for me, but I have the odd problem with version 1, and only version 10 seems to be supported these days.

Francois Piette's ICS is pretty easy to work with by using the <CRLF> as a delimiter for commands. (WriteLn, etc)
It's very simple, non blocking, and like Indy, has quite a few demos available for it. It does not (by default) use threads, so it has a lower server overhead.

Let me know if you'd like me to make a demo in either Indy or ICS, and if you require streaming data or just text commands/responses
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question