Solved

My commands doesn't reach the host!

Posted on 2006-06-13
8
194 Views
Last Modified: 2010-04-05
Dear Experts,

In my previous question I have asked:

“When I put my component on the form with Align = alClient
and assign the event OnSendData to the procedure
TForm1.DSP32701SendData(Sender: TObject; Data: String);
and then when I press F9 to run, I get the logon-screen
of the host, but when I enter the Userid + password and then
press Enter nothing happends”.

Ciuly adviced me to make a logging system in my component
so I did.

Results:
When I make a connection to the mainframe with the programm
that I have found on the internet, I get the same logging output
as when I make a connection to the mainframe with my component.
So, I quess that’s OK.

But, when I enter a userid + password with the original program
I get a lot of output, and when I enter userid + password with
my component, I just get a few lines!
Conclussion: My commands doesn’t reach the host.

There are 3 procedures in my component, that goes to the procedure
TForm1.DSP32701SendData(Sender: TObject; Data: String); on the main form.
and there is 1 procedure called MakeConnect on the mainform that goes also
to the procedure TForm1.DSP32701SendData(Sender: TObject; Data: String);

type
  TOnSendData       =  procedure(Sender: TObject; Data: String) of object;
  TDSP3270         =  class(TComponent)
  private
     // Private declarations
     FOnSendData:   TOnSendData;
  protected
     // Protected declarations
  public
     // Public declarations
  published
     // Published declarations
     property       OnSendData: TOnSendData read FOnSendData write FOnSendData;
  end;

type
  TForm1            = class(TForm)
     procedure      FormCreate(Sender: TObject);
  private
     // Private declarations
  public
     // Public declarations
     procedure DSP32701SendData(Sender: TObject; Data: String);
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

procedure TDSP3270.DataOut(key: byte);
var obuf: string ;
     ba1, ba2: byte ;
begin
  ReadModified(obuf) ;
  rc2sba(fCsrRow,fCsrCol,ba1,ba2) ;
  obuf := Char(key) + Char(ba1) + Char(ba2) + obuf ;
  LockKeyBoard('SYSTEM',NOALARM) ;
  if Assigned(FOnSendData) then FOnSendData(Self, obuf);
end ;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ConnectHostName :=('145.70.16.2');
  DSP32701.OnSendData:= DSP32701SendData;
end;

procedure TForm1.DSP32701SendData(Sender: TObject; Data: String);
const
  C_CR    = $0A ; { carrage return }
  C_LF    = $0D ; { line feed }
type
  TOutBuf = array[0..4096] of char ;
var
  err: integer ;
  size: integer ;
  pc: PChar ;
  OutBuffer: TOutBuf ;
  i: integer ;
begin
  if EorFlag then
    data := data + Char(IAC) + Char(C_EOR) ;
  pc := @OutBuffer ;
  StrPCopy(pc,data) ;
  size := Length(data) ;
  err := send(soc,OutBuffer,size,0) ;
  if err = SOCKET_ERROR then
    Log('Send error: '
      +Format('%d',[WSAGetLastError()]))
  else
    begin
      if deb then
        begin
          Log('Send: '+Format(' (%d)',[size])) ;
          for i:=0 to (size-1) do
            DumpChar(OutBuffer[i]) ;
          DumpFlush ;
        end ;
    end ;
end;

procedure TForm1.MakeConnect;
type
  TPint = ^Longint ;
var
  err: integer ;
  phost: PHostEnt ;
  ina: TInAddr ;
  lina: TInAddr ;
  pint: TPint ;
  RemoteHostName: TPath ;
         etc... etc...
   if deb then
    Log('Connected.') ;
    RecvThrd.Create(soc, DSP32701);
   { send CR LF to get server started }
    DSP32701SendData(self,InitCmd);    //this line calls the DSP3270Senddate-procedure
         etc.. etc...
  end;
end;
 
end.

I hope someone can help me.

Greetings,

Peter Kiers
0
Comment
Question by:peterkiers
  • 5
  • 3
8 Comments
 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
most command servers expect to receive a CR/LF pair at the end of each line
eg. 'hello' + #13#10
so in your example, try this
data := data + #13#10;
before you send it
0
 
LVL 1

Author Comment

by:peterkiers
Comment Utility
Doesn't work.

Can somebody help me with this problem because I think that
the solution to my problem:

I have to hook up 3 procedures in my component TDSP3270 to a procedure on the main form:
How can I do that, I know I have asked this before, but the answer didn't work.

procedure TDSP3270.DataIn(buf: string);
var
  cmd: byte ;
  obuf: string ;
  ba1, ba2: byte ;
begin
  cmd := Byte(buf[1]) ;
  case cmd of
    IC_EAU: { Erase All Unprotected }
      begin
        if deb then
        Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        DoWccStart(buf[2]) ;
        EraseUnprotected ;
        DoWccEnd(buf[2]) ;
        ShowBuf ;
      end ;
    IC_EW:  { Erase Write }
      begin
        if deb then
          Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        DoWccStart(buf[2]) ;
        ClearScr ;
        WriteData(buf) ;
        DoWccEnd(buf[2]) ;
        ShowBuf ;
      end ;
    IC_EWA: { Erase Write Alternate }
      begin
        if deb then
          Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        DoWccStart(buf[2]) ;
        ClearScr ;
        WriteData(buf) ;
        DoWccEnd(buf[2]) ;
        ShowBuf ;
      end ;
    IC_RB:  { Read Buffer }
      begin
        if deb then
          Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        ReadBuffer(obuf) ;
        rc2sba(fCsrRow,fCsrCol,ba1,ba2) ;
        obuf := Char(ckAidNone) + Char(ba1) + Char(ba2) + obuf ;
        //SendData(obuf) ;
        if deb then
          LogDsOut(obuf) ;
      end ;
    IC_RM:  { Read Modified }
      begin
        if deb then
        Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        ReadModified(obuf) ;
        rc2sba(fCsrRow,fCsrCol,ba1,ba2) ;
        obuf := Char(ckAidNone) + Char(ba1) + Char(ba2) + obuf ;
     //  SendData(obuf) ;                                             //calls for Senddata on the mainform
        if deb then
          LogDsOut(obuf) ;
      end ;
    IC_W:   { Write }
      begin
        if deb then
        Logf.Memo1.Lines.Add('  Cmd: EUA') ;
        DoWccStart(buf[2]) ;
        WriteData(buf) ;
        DoWccEnd(buf[2]) ;
        ShowBuf ;
      end ;
    IC_NOP: { No Opperation }
      NotImplemented('NOP') ;
    IC_WSF: { Write Structured Field }
      NotImplemented('WSF') ;
  else
    Logf.Memo1.Lines.Add(Format('Invalid 3270 command: %.2x',[cmd]) ) ;
  end ;  { of case }
  UnLockKeyBoard ;
end ;

procedure TDSP3270.DataOut(key: byte);
var
  obuf: string ;
  ba1, ba2: byte ;
begin
  ReadModified(obuf) ;
  rc2sba(fCsrRow,fCsrCol,ba1,ba2) ;
  obuf := Char(key) + Char(ba1) + Char(ba2) + obuf ;
  LockKeyBoard('SYSTEM',NOALARM) ;
  //SendData(obuf) ;                                     //calls for Senddata on the mainform
  if deb then
    LogDsOut(obuf) ;
end ;

procedure TDSP3270.DataOutShort(key: byte);
begin
  LockKeyBoard('SYSTEM',NOALARM) ;
 // SendData(Char(key)) ;                              //calls for Senddata on the mainform
  if deb then
    LogDsOut(Char(key)) ;
end ;

procedure TForm1.SendData(sdata: string);
const
  C_CR    = $0A ; { carrage return }
  C_LF    = $0D ; { line feed }
type
  TOutBuf = array[0..4096] of char ;
var
  err: integer ;
  size: integer ;
  pc: PChar ;
  OutBuffer: TOutBuf ;
  i: integer ;
begin                
  if EorFlag then
    sdata := sdata + Char(IAC) + Char(C_EOR) ;
  pc := @OutBuffer ;
  StrPCopy(pc,sdata) ;
  size := Length(sdata) ;
  err := send(soc,OutBuffer,size,0) ;
  if err = SOCKET_ERROR then
    Log('Send error: '
      +Format('%d',[WSAGetLastError()]))
  else
    begin
      if deb then
        begin
          Log('Send: '+Format(' (%d)',[size])) ;
          for i:=0 to (size-1) do
            DumpChar(OutBuffer[i]) ;
          DumpFlush ;
        end ;
    end ;
end;
0
 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
you would normally have your notify called like this :-

if assigned(FOnSendData) then FOnSendData(self, obuf)

instead of
   //  SendData(obuf) ;                                             //calls for Senddata on the mainform
0
 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
so I think it's like this :-

type
  TOnSendData       =  procedure(Sender: TObject; Data: String) of object;
  TOnDataIn = procedure(Sender: TObject; buf: string) of object;
  TOnDataOut = procedure(Sender: TObject; key: byte); of object;
  TOnDataOutShort = procedure(Sender: TObject; key: byte); of object;

  TDSP3270         =  class(TComponent)
  private
     // Private declarations
     FOnSendData:   TOnSendData;
     FOnDataIn:   TOnDataIn;
     FOnDataOut:   TOnDataOut;
     FOnDataOutShort:   TOnDataOutShort;
  protected
     // Protected declarations
  public
     // Public declarations
  published
     // Published declarations
     property       OnSendData: TOnSendData read FOnSendData write FOnSendData;
     property       OnDataIn: TOnDataIn read fOnDataIn write fOnDataIn;
     property       OnDataOut: TOnDataOut read fOnDataOut write fOnDataOut;
     property       OnDataOutShort: TOnDataOutShort read fOnDataOutShort write fOnDataOutShort;
  end;

type
  TForm1            = class(TForm)
     procedure      FormCreate(Sender: TObject);
  private
     // Private declarations
  public
     // Public declarations
     procedure DSP32701SendData(Sender: TObject; Data: String);
     procedure DSP32701DataIn(Sender: TObject; buf: string);
     procedure DSP32701DataOut(Sender: TObject; key: byte);
     procedure DSP32701DataOutShort(Sender: TObject; key: byte);
  end;


...
if assigned(fOnDataIn) then fOnDataIn(self, buf);
..
if assigned(fOnDataOut) then fOnDataOut(self, key);
..
if assigned(fOnDataOutShort) then fOnDataOutShort(self, key);
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
oh and of course (almost forgot)

procedure TForm1.FormCreate(Sender: TObject);
begin
  DSP3270.OnSendData:=Self.DSP32701SendData;
  DSP3270.OnDataIn:=Self.DSP32701DataIn;
  DSP3270.OnDataOut:=Self.DSP32701DataOut;
  DSP3270.OnDataOutShort:=Self.DSP32701DataOutShort;

end;
0
 
LVL 1

Author Comment

by:peterkiers
Comment Utility
Hi, I did everything you wrote:

But I get a few errors:
rror] Main.pas(1072): Undeclared identifier: 'fOnDataIn'
[Error] Main.pas(1072): Incompatible types
[Error] Main.pas(1077): Undeclared identifier: 'fOnDataOut'
[Error] Main.pas(1077): Incompatible types
[Error] Main.pas(1082): Undeclared identifier: 'fOnDataOutShort'

procedure TForm1.DSP32701DataIn(Sender: TObject; buf: string);
begin
if assigned(fOnDataIn) then fOnDataIn(self, buf);
end;

procedure TForm1.DSP32701DataOut(Sender: TObject; key: byte);
begin
 if assigned(fOnDataOut) then fOnDataOut(self, key);
end;

procedure TForm1.DSP32701DataOutShort(Sender: TObject; key: byte);
begin
  if assigned(fOnDataOutShort) then fOnDataOutShort(self, key);
end;
0
 
LVL 17

Accepted Solution

by:
TheRealLoki earned 500 total points
Comment Utility
hmmm, perhaps I misunderstood your post.
do you want to have those 3 procedures in the main form, or do you just want those 3 procedures to call 1 procedure in the main form?

if you want those 3 procedures to be in the main form, then make sure you have this part
private
     // Private declarations
     FOnSendData:   TOnSendData;
     FOnDataIn:   TOnDataIn;
     FOnDataOut:   TOnDataOut;
     FOnDataOutShort:   TOnDataOutShort;


If you just wanted those 3 procedures to call your existing "DSP3270.OnSendData" method then all you actually had to do was :-
if assigned(FOnSendData) then FOnSendData(self, obuf);
in all those locations


0
 
LVL 1

Author Comment

by:peterkiers
Comment Utility
OKE, thank you.

Peter Kiers
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

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 I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

771 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now