Recent

Author Topic: [SOLVED] Synapse what's wrong?  (Read 2958 times)

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
[SOLVED] Synapse what's wrong?
« on: May 14, 2020, 11:43:27 am »
Hello!

I did this code and it's can connect, but can't send messages to each other. :(
why?

server:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  9.   laz_synapse, blcksock;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     Edit1: TEdit;
  19.     Edit2: TEdit;
  20.     Memo1: TMemo;
  21.     Timer1: TTimer;
  22.     procedure Button1Click(Sender: TObject);
  23.     procedure Button2Click(Sender: TObject);
  24.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  25.     procedure FormCreate(Sender: TObject);
  26.     procedure Timer1Timer(Sender: TObject);
  27.   private
  28.  
  29.   public
  30.  
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42.  var listenersocket:TBlockSocket;
  43.      connection:TBlockSocket;
  44.      socknum:integer;
  45.      connected:boolean;
  46.      commessage:string;
  47.  
  48. procedure TForm1.Button1Click(Sender: TObject);
  49.  var sz:integer;
  50. begin
  51.   //HOST
  52.  
  53.   listenersocket:=TBlockSocket.Create;
  54.   listenersocket.CreateSocket;
  55.   if Edit1.Text='' then Edit1.Text:='11';
  56.   listenersocket.Bind('192.168.0.101',Edit1.Text);
  57.   listenersocket.Listen;
  58.  
  59.   repeat
  60.       Application.ProcessMessages;
  61.       if listenersocket.CanRead(10) then begin
  62.         connection:=TBlockSocket.Create;
  63.         connection.Socket:=listenersocket.Accept;
  64.         connected:=true;
  65.         memo1.Append('connection setted up!');
  66.       end;
  67.   until false;
  68.  
  69. end;
  70.  
  71. procedure TForm1.Button2Click(Sender: TObject);
  72.  var sz:integer;
  73.      message:string;
  74. begin
  75.   if connected=true then begin
  76.     message:=Edit2.Text;
  77.     connection.SendString(message);
  78.  
  79.   end;
  80. end;
  81.  
  82. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  83. begin
  84.   halt;
  85. end;
  86.  
  87. procedure TForm1.FormCreate(Sender: TObject);
  88. begin
  89.   socknum:=1;
  90. end;
  91.  
  92. procedure TForm1.Timer1Timer(Sender: TObject);
  93.   var sz:integer;
  94. begin
  95.    Application.ProcessMessages;
  96.   if connected=true then begin
  97.       commessage:=connection.RecvString(10);
  98.       if commessage<>'' then Memo1.Lines.Append(commessage);
  99.     end;
  100. end;
  101.  
  102. end.
  103.  
  104.  

client:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  9.   laz_synapse, blcksock;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     Edit1: TEdit;
  19.     Edit2: TEdit;
  20.     Edit3: TEdit;
  21.     Memo1: TMemo;
  22.     Timer1: TTimer;
  23.     procedure Button1Click(Sender: TObject);
  24.     procedure Button2Click(Sender: TObject);
  25.     procedure FormCreate(Sender: TObject);
  26.     procedure Timer1Timer(Sender: TObject);
  27.   private
  28.  
  29.   public
  30.  
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42. var connection:TBlockSocket;
  43.     connected:boolean;
  44.     messagein:string;
  45.  
  46. procedure TForm1.FormCreate(Sender: TObject);
  47. begin
  48. end;
  49.  
  50. procedure TForm1.Timer1Timer(Sender: TObject);
  51. begin
  52.   Application.ProcessMessages;
  53.   if connected=true then begin
  54.     messagein:=connection.RecvString(10);
  55.     if not(messagein='') then begin
  56.       Memo1.Append(messagein);
  57.     end;
  58.   end;
  59. end;
  60.  
  61. procedure TForm1.Button1Click(Sender: TObject);
  62.   var sz:integer;
  63.       sz2:integer;
  64. begin
  65.   //Connect
  66.   if Edit1.Text='' then Edit1.Text:='192.168.0.101';
  67.   if Edit2.Text='' then Edit2.Text:='11';
  68.  
  69.   connection:=TBlockSocket.Create;
  70.   connection.CreateSocket;
  71.   connection.Connect(Edit1.Text,Edit2.Text);
  72.  
  73.   if connection.LastError=0 then begin
  74.     connected:=true;
  75.     Memo1.Lines.Append('Connected!');
  76.   end;
  77.  
  78. end;
  79.  
  80. procedure TForm1.Button2Click(Sender: TObject);
  81.   var message:string;
  82. begin
  83.   if connected=true then begin
  84.     message:=Edit3.Text;
  85.     connection.SendString(message);
  86.   end;
  87. end;
  88.  
  89. end.
  90.  
  91.  

Thanks for solution!
« Last Edit: May 15, 2020, 05:27:33 pm by Jake012345 »

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Synapse what's wrong?
« Reply #1 on: May 14, 2020, 12:09:01 pm »
The problem is that you don't work with threads.

In Button1Click in the server you have a repeat until false. You never leave that event. Therefore the timer-event will never trigger. TTimer events are executed in the main thread but if you have a 'hanging' event procedure it will never come to that.

So make sure the Button1Click event ends before you can read from the connection.
Or better, use threads.

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Synapse what's wrong?
« Reply #2 on: May 14, 2020, 12:37:07 pm »
But how can I test it?
Or make threads?

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Synapse what's wrong?
« Reply #3 on: May 14, 2020, 02:34:50 pm »
But how can I test it?
Or make threads?
To test it you could do an break inside the repeat until loop.
Below the memo1.Append('connection setted up!');

In that case, when the first connection is setup, the program will run on and your timer will function.
But it will only work once for the first connection you do.

When you end the connection and click the server button again, you'll get errors because there is already a listening socket (which you can't use anymore because you exited the function before).

If you really don't want to work with threads you need to setup the listening socket in formcreate (or in a special StartServer function) which you only execute once. Then the listening loop can be run (with another button or automatically). When the connection is terminated you can again run the loop function to listen for another connection.

But it would be better to move everything to a thread. In that case you can spawn multiple connections and receive messages from multiple clients.

In the standard .zip download of version 40 you'll find an example.
synapse40\source\demo\echo\echo.pas

(Although it's best you work with the trunk version at https://sourceforge.net/p/synalist/code/HEAD/tree/trunk/ (use the download button right above) the examples are only to be found in the synapse40.zip)

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: Synapse what's wrong?
« Reply #4 on: May 14, 2020, 03:53:01 pm »
In Button1Click in the server you have a repeat until false. You never leave that event. Therefore the timer-event will never trigger.

That's not quite true, is it? Note that he calls ProcessMessages in the very first line of the loop so the timer messages should be getting through on each iteration.

Though I'll agree with you that in this case he would be better off using threads  :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Synapse what's wrong?
« Reply #5 on: May 14, 2020, 03:54:16 pm »
:(

Can You share an example?
I can't do it not at all...

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Synapse what's wrong?
« Reply #6 on: May 14, 2020, 05:10:45 pm »
In Button1Click in the server you have a repeat until false. You never leave that event. Therefore the timer-event will never trigger.
That's not quite true, is it? Note that he calls ProcessMessages in the very first line of the loop so the timer messages should be getting through on each iteration.
Yes, You are correct about the ProcessMessages.

Can You share an example?
I can't do it not at all...
I don't have time now to create a complete example but the echo.pas I mentioned has a thread example.

For your current code... you shouldn't use such low port number like 11. Use something high like 20011.
(I'm not sure why your example doesn't run, because like lucamar mentioned, it should work because of the processmessages)

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Synapse what's wrong?
« Reply #7 on: May 15, 2020, 12:48:17 pm »
Okay, I got something!!

If the connection done, the server can see it, but the client no. (?!!?)
But if I send something to client and the client has a procedure,

for example:
Code: Pascal  [Select][+][-]
  1. If connection.CanRead(100) then
  2.   Memo1.Append('Got it!');
  3.  

the client show the 'Got it!' message. Every time when I send something from server. But I can't read the messages yet..

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Synapse what's wrong?
« Reply #8 on: May 15, 2020, 12:54:47 pm »
Aaaaargh. You are correct.

Look at http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket.html#SendString

When using sendstring the crlf is not send with it.
Although the recvstring does wait until it receives a crlf termination.
So, add the CR-LF in every sendstring and it schould work.

Note: the canread does see there is data but the recvstring waits until it has the linetermination.

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Synapse what's wrong?
« Reply #9 on: May 15, 2020, 02:49:24 pm »
I can't understand it...
I added CR+LF to programs

Code: Pascal  [Select][+][-]
  1. messageout:=(Edit2.Text);
  2. cinnection.SendString(messageout+CR+LF);
  3.  

But the server can read the incoming messages after sending (so if I sent something to server, I can't see until I press the send button and send something)

If I used the wrong timeouts, (timer.interval=50, but the timeouts=1000)
the client could receive the messages and show it until freezing...
But I repaired the timeouts (timer.interval=1000, timeouts=10)
And the procedure what I wrote in timer too,

Code: Pascal  [Select][+][-]
  1.   Application.ProcessMessages;
  2.  
  3.    if connected=true then
  4.     if connection.CanRead(10) then begin
  5.        Application.ProcessMessages;
  6.       messagein:=connection.RecvString(10);
  7.       if not(messagein='') then begin
  8.         Memo1.Append(messagein);
  9.       end;
  10.     end;
  11.  
  12. if k=0 then                                              //<--
  13.  if connected=true then                                 //<--
  14.   if connection.LastError=0 then begin                 //<--
  15.     Memo1.Lines.Append('Connected!');                 //<--   This
  16.     s:=connection.GetRemoteSinIP;                    //<--
  17.     memo1.Append(s);                                //<--
  18.     k:=1;                                          //<--
  19.   end;                                            //<--
  20.  

Always run,  BUT just when I move the window. (??!!)
Why don't like me the synapse?  :'(
« Last Edit: May 15, 2020, 02:51:48 pm by Jake012345 »

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Synapse what's wrong?
« Reply #10 on: May 15, 2020, 04:54:47 pm »
I can't understand it...
I added CR+LF to programs
I'm not sure what goes wrong at your end.
I have the timer in both programs set to 10 (although it could slightly be higher).
I have the exact same code from your opening post.
Added  + #13#10 to the SendString() in both programs and ran them.

I can type and receive with both programs without delay and freeze.

Try to revert to your code from the opening post.
After that you can add new things.

It is indeed best to check if there is data in TTimer before firing RcvString() but try it without first (like in your opening post).

B.T.W. You can use 0.0.0.0 as ip adres on the server for binding (listening on all network interfaces).
The client should indeed use the ip from the server.
I still think port 11 should be avoided but it does work (better to use a random port > 1024)
11 is used by other services. https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
So choose one above 1024 which isn't already listed as reserved in the link above.

Jake012345

  • Sr. Member
  • ****
  • Posts: 270
  • Knowledge is the key
Re: Synapse what's wrong?
« Reply #11 on: May 15, 2020, 05:27:16 pm »
WORKING!!!!!!!!!!

Thanks my god!
Thanks @rvk!
And @lucamar, for useful info.

 

TinyPortal © 2005-2018