Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Jul : Works with one Socket but not two

www.cryer.info
Managed Newsgroup Archive

Works with one Socket but not two

Subject:Works with one Socket but not two
Posted by:"ChickenCoder" (larrykill..@gainco.com)
Date:Fri, 11 Jul 2008 17:12:18

I have stripped the code to the base essentials to still create the problem.
My intentions are to create instaces of a Scale class that has a listening
client.  IT works if I only have one scale set in my database but will not
even get to FormShow if I set it up for two.  On FormCreate, I make a
ScaleList (probably not neccesary since I never need to access the scale
object, once created) .

The CreateScale loops throught he databse to make a Scale instance which in
turn, creates a TReadingInfinitiThread instance.


I guess I have the thread instanciation screwed up.  Am I even close to
doing this right?

Thanks,
Larry
=======================================================================================
unit uMain;

interface

uses ...

type
  TScale = class
  private
    fScaleID: Integer;
    fPortNbr: Integer;
    fIPaddr: String;
    fActive: Boolean;
    fScaleName: String;

  public
    ReadingInfinitiThread : TReadingInfinitiThread;
    Property ScaleName    : String read fScaleName;
    Property ScaleID      : Integer read fScaleID;
    Property PortNbr      : Integer read fPortNbr;
    Property IPaddr       : String read fIPaddr;
    Property Active       : Boolean read fActive;
    //constructor
    Constructor Create( Const ScaleName : String;
                        Const ScaleID   : Integer;
                        Const PortNbr   : Integer;
                        Const IPaddr    : String;
                        Const Active    : Boolean);
end;

type
  TfrmMain = class(TForm)
    pnlMid: TPanel;
    StatusBar1: TStatusBar;
    ToolBar1: TToolBar;
    Splitter1: TSplitter;
    pnlBottom: TPanel;
    Memo1: TMemo;

    procedure Memo1DblClick(Sender: TObject);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);

    procedure FormCreate(Sender: TObject);

  private

    FConnInCritSec: TCriticalSection;
    fActiveSetID: Integer;

    { Private declarations }
  public
    { Public declarations }
     fBroadCast: String;

     ScaleList : TObjectList;
    Procedure DisplayBroadcast;

    procedure MakeCriticalSections;
    procedure CreateScale;
    Property ActiveSetID : Integer read fActiveSetID write fActiveSetID;
    Property ConnInCritSec  : TCriticalSection read FConnInCritSec;
end;

var
  frmMain: TfrmMain;

implementation

uses uDMmain, raw_ping, ABOUT;

{$R *.dfm}


procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ScaleList.Free;
  Action := caFree;
end;

procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
    FConnInCritSec.Free;
    application.Terminate;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin

  MakeCriticalSections;

  ScaleList := TObjectList.Create(True);
  CreateScale;
end;


procedure TfrmMain.MakeCriticalSections;
begin
  FConnInCritSec  := TCriticalSection.Create;
end;

procedure TfrmMain.Memo1DblClick(Sender: TObject);
begin
  Memo1.Clear;
end;

procedure TfrmMain.CreateScale;
var
  tScaleName : string;
  tScaleID   : integer;
  tPortNbr   : integer;
  tIPaddr    : string;
  tActive    : Boolean;

begin
  Try
    dmMain.qrySettings.open;
    With dmMain.qrySettings do
    Begin
      While Not(Eof) do
      Begin
        tScaleName :=  FieldByName('ScaleName').AsString;
        tScaleID   :=  FieldByName('ScaleID').AsInteger;
        tPortNbr   :=   FieldByName('Port').AsInteger;
        tIPaddr    :=   FieldByName('IPAddress').AsString;
        tActive    :=  FieldByName('Active').AsBoolean;
        ScaleList.Add(TScale.Create(tScaleName, tScaleID, tPortNbr, tIPaddr,
tActive));
        Next;
      End;
    End;

  Finally
    dmMain.qrySettings.close;
  End;
end;


procedure TfrmMain.DisplayBroadcast;
begin
  Memo1.Lines.Add(fBroadcast);
end;

{ TScale }

constructor TScale.Create(const ScaleName: String; const ScaleID,
  PortNbr: Integer; const IPaddr: String; const Active: Boolean);

Begin
  fScaleName := ScaleName;
  fScaleID := ScaleID;
  fPortNbr := PortNbr;
  fIPaddr := IPaddr;
  fActive := Active;
  ReadingInfinitiThread := TReadingInfinitiThread.Create(fPortNbr, fIPaddr,
fScaleID);
end;

end.

========================================================================================
unit ReadInfiniti;

interface

uses
  Classes, IdTCPClient, StrUtils, forms, SysUtils, AdoDb, Windows,
   IdTCPConnection;
type
  TReadingInfinitiThread = class(TThread)
  private
    { Private declarations }
    FConn: TIdTCPClient;
    Buffer : string;
    FBroadcast  : string;

    procedure DisplayData;
  protected

    procedure Execute; override;
  public

    procedure AfterConstruction; override;
    constructor Create(Port:integer; IPAddr:String; ScaleID : Integer);
reintroduce;

  end;

implementation

uses uMain, IdIOHandler, uDM, dialogs;

{ TReadingInfinitiThread }

procedure TReadingInfinitiThread.AfterConstruction;
begin
  inherited;
  Resume;
  FConn.Connect;
  If FConn.Connected then
  FConn.IOHandler.Write(Byte(22)); //SYN
end;

procedure TReadingInfinitiThread.DisplayData;
begin
  frmMain.ConnInCritSec.Enter;
  try
     frmMain.fBroadCast := FBroadcast;
     frmMain.DisplayBroadcast;
  finally
     frmMain.ConnInCritSec.Leave;
  end;
end;

constructor TReadingInfinitiThread.Create(Port:integer; IPAddr:String;
ScaleID : Integer);
begin
  inherited Create(True);
  beep(1000, 100);
  Priority := tpLower;

  try
    FConn := TIdTCPClient.Create(application);
    with FConn do
    begin
      ConnectTimeout := 0;
      Port := 9100;//Port;
      Host := IPAddr;
      ReadTimeout := -1;
    end;

  except
    on e:exception do
    Begin
      FBroadcast := e.Message+' for scale '+IntToStr(ScaleID);
      DisplayData;
    End;
  end;
end;

procedure TReadingInfinitiThread.Execute;
begin
    while not Terminated do
    begin
      case FConn.IOHandler.ReadByte of
        $02: // STX
          begin
            Buffer := FConn.IOHandler.ReadLn(Chr(3));
            FBroadcast := 'Buffer '+ Buffer;
            DisplayData;
          end;            // to be picked up by a second thread
        else
        Begin
          FBroadcast := 'unknown character';
          DisplayData;
        End;
      end; //case
    end;
end;

end.

Replies:

www.cryer.info
Managed Newsgroup Archive