Recent

Author Topic: Korg Remote Desktop  (Read 9501 times)

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #30 on: November 18, 2020, 03:22:13 pm »
I created a small test example (taken from the KRD code). Could you try it out and tell me if I am doing something wrong in implementing UDP hole punching? So at least we talk looking at the same code and we can't get it wrong.
Locally it works. Although procedure to start a connection could be made somewhat easier.
Now both need to start P2P manually while the controller should send an invite to B when A wants to connect and B should acknowledge with messaging port, and controller should send that back to A.

I even wonder if A uses messaging port 1985 to connect to the controller. If it doesn't, there is the problem. No hole punching.

I also do not see any message in the controller where the extIP:extPort of A is send to B and visa versa.
That needs to be send in a string because A and B don't know each others extIP:extPort.
(But I could be wrong)

Need to test some more with a computer on the internet.

Edit:

Just curious... but isn't the client sending the strings here to the controller????
Shouldn't it send it directly to the other client?

Was just a wrong name there. It should be remote_ip, not ControllerIP.

Code: Pascal  [Select][+][-]
  1.      for i:=1 to 10 do
  2.      begin
  3.           Msg := ControllerMyId + ' msg_' + IntToStr(i);
  4.           app.SendString(Msg, ControllerIp, ControllerPort);
  5.           Self.Memo1.Append(ControllerIp + ':' + IntToStr(ControllerPort) + ' --> ' + Msg);
  6.           Sleep(100);
  7.           Msg := app.GetString(ip_r, port_r, 1000);
  8.           if Msg<>'' then
  9.           begin
  10.                Self.Memo1.Append(ip_r + ':' + IntToStr(port_r) + ' <-- ' + Msg);
  11.           end;
  12.           Application.ProcessMessages;
  13.      end;
« Last Edit: November 18, 2020, 03:36:08 pm by rvk »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #31 on: November 18, 2020, 03:32:01 pm »
Yes, I know the procedure can be simplified, and I'll do it when the rest works.

Open uUDPHolePunchingControllerClient.pas you will see that in the thread execute I go to request the information from the controller of the other client. When it finds them, it passes them to the form through the SendInfoMain procedure

Code: Pascal  [Select][+][-]
  1. procedure TUDPHolePunchingControllerClient.SendInfoMain(MyId: string;
  2.   ip_r: string; port_r: integer);
  3. begin
  4.      EnterCriticalsection(Form1.UDPCriticalSectionController);
  5.  
  6.      Form1.ControllerMyId := MyId;
  7.      Form1.ControllerIp   := ip_r;
  8.      Form1.ControllerPort := port_r;
  9.      Form1.ControllerTS   := Self.FTypeOfSession;
  10.      Synchronize(@Form1.ControllerAction);
  11.  
  12.      LeaveCriticalsection(Form1.UDPCriticalSectionController);
  13. end;
  14.  

This should answer your questions
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #32 on: November 18, 2020, 04:26:22 pm »
How did you test this on the internet?

Because... I don't think you can test it with the controller on the same network as one of the clients.
Both clients need to be another network then that of the controller.
(but they should be able to be on the same network as each other)

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #33 on: November 18, 2020, 05:51:28 pm »
I have a virtual private server with a public IP address. So no NAT and I use it as a controller.

In fact, the connections to the controller occur regularly. Only P2P doesn't work.

Then client A use it over the home network


I use client B through the mobile hotspot.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #34 on: November 18, 2020, 08:48:29 pm »
Seems like the ports aren't correctly translated.
I keep getting my_external_ip:5000 and 4999.
Even if I set it to port 80 I get my_external_ip:80. And I know for sure my router doesn't use external port 80 because that's already used by another computer via port forwarding.

So it looks like sock.GetRemoteSinPort doesn't provide the correct port.

I do see the UDP messages from client controlport to the controller (although the external port is 'wrong').
But do you also send a message to the controller on port 5000 when you press Start P2P?
(not just a stringmessage on the controlport)

It needs to do that because at THAT point you need to record the external port (internal 5000->external) into a table and send that to the other client.

Or does the communication happen over the controlport? (for which a hole is already punched)

What I also find strange is that when I use port 9090 as controlport on the client, and have 9090 UDP as port forwarded to a totally different computer, I still get a new ID on that client.
« Last Edit: November 18, 2020, 09:21:55 pm by rvk »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #35 on: November 18, 2020, 10:00:19 pm »
When you press "Start P2P" you use the SetTypeIpPort command which sends a message to the controller. The controller retrieves the message and through the sock.GetRemoteSinPort retrieves the port (in addition to having also retrieved the ip with the sock.GetRemoteSinIp function).

No, port 5000 is what I use. That is the port of my pc from which I send the message.

Isn't your port forwarding acting on the tcp protocol and not on udp ?!

I didn't understand the last part of your message.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #36 on: November 18, 2020, 11:02:55 pm »
No, I set forward port 9090 UDP to a totally different computer and if I use 9090 for controlport and I still get a 9090 on the controller as remoteport. That shouldn't be possible because I bind it to internal 9090 and it should get a random other port as remote on the other side because while listening on imternal 9090 I can't use 9090 to send messages to (because it's forwarded to somewhere else).

Unless I totally missed the point with UDP... you can see it with TCP. For example looking at a phpinfo page you see a remote_port which is different from port 80. Maybe udp works differently.

But I tried a small example.. and you can only do sendstring on controller to a client where the client has done connect to the controller. If you use a different socket to send a message to the controlport of a client, it doesn't work. Which leads me to believe that synapse keeps an internal connection for that connection.

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #37 on: November 19, 2020, 08:10:07 am »
At this point perhaps it is worth reporting the thread on the synapse forum. What do you think about it?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #38 on: November 19, 2020, 09:24:29 am »
At this point perhaps it is worth reporting the thread on the synapse forum. What do you think about it?
Maybe.

I tried a simple example.

This on the client side (80.80.80.80)
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   sock1: TUDPBlockSocket;
  4.   Value: ansistring;
  5. begin
  6.  
  7.   sock1 := TUDPBlockSocket.Create;
  8.   sock1.OnStatus := @OnStatus;
  9.   sock1.CreateSocket;
  10.   sock1.bind('0.0.0.0', '9090');
  11.   sock1.SetRemoteSin('84.84.84.84', '1985');
  12.   sock1.SendString('testtesttest' + #13 + #10);
  13.   sock1.Free;
  14.  
  15.   sock1 := TUDPBlockSocket.Create;
  16.   sock1.OnStatus := @OnStatus;
  17.   sock1.CreateSocket;
  18.   sock1.bind('0.0.0.0', '9090');
  19.   while True do
  20.   begin
  21.     if sock1.CanRead(1000) then
  22.     begin
  23.       Value := sock1.RecvString(500);
  24.       Memo1.Lines.Add('recv: ' + Value);
  25.       Memo1.Lines.Add(sock1.GetRemoteSinIP + ' : ' + sock1.GetRemoteSinPort.ToString);
  26.       break;
  27.     end;
  28.     Application.ProcessMessages;
  29.   end;
  30.   sock1.Free;
  31.   Memo1.Lines.Add('---');
  32.  
  33. end;
  34.  
  35. procedure TForm1.OnStatus(Sender: TObject; Reason: THookSocketReason; const Value: string);
  36. var
  37.   sReason: string;
  38. begin
  39.   case Reason of
  40.     HR_ResolvingBegin: sReason := 'HR_ResolvingBegin';
  41.     HR_ResolvingEnd: sReason := 'HR_ResolvingEnd';
  42.     HR_SocketCreate: sReason := 'HR_SocketCreate';
  43.     HR_SocketClose: sReason := 'HR_SocketClose';
  44.     HR_Bind: sReason := 'HR_Bind';
  45.     HR_Connect: sReason := 'HR_Connect';
  46.     HR_CanRead: sReason := 'HR_CanRead';
  47.     HR_CanWrite: sReason := 'HR_CanWrite';
  48.     HR_Listen: sReason := 'HR_Listen';
  49.     HR_Accept: sReason := 'HR_Accept';
  50.     HR_ReadCount: sReason := 'HR_ReadCount';
  51.     HR_WriteCount: sReason := 'HR_WriteCount';
  52.     HR_Wait: sReason := 'HR_Wait';
  53.     HR_Error: sReason := 'HR_Error';
  54.   end;
  55.   Memo1.Lines.Add(sReason + ' ' + Value);
  56. end;

and this on the controller side (84.84.84.84):
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   sock1: TUDPBlockSocket;
  4.   Value: ansistring;
  5.   eIP, ePort: string;
  6. begin
  7.  
  8.   sock1 := TUDPBlockSocket.Create;
  9.   sock1.OnStatus := @OnStatus;
  10.   sock1.CreateSocket;
  11.   sock1.bind('0.0.0.0', '1985');
  12.   while True do
  13.   begin
  14.     if sock1.CanRead(1000) then
  15.     begin
  16.       Value := sock1.RecvString(500);
  17.       Memo1.Lines.Add('recv: ' + Value);
  18.       Memo1.Lines.Add(sock1.GetRemoteSinIP + ' : ' + sock1.GetRemoteSinPort.ToString);
  19.       eIp := sock1.GetRemoteSinIP;
  20.       ePort := sock1.GetRemoteSinPort.ToString;
  21.       break;
  22.     end;
  23.     Application.ProcessMessages;
  24.   end;
  25.   sock1.Free;
  26.  
  27.   sock1 := TUDPBlockSocket.Create;
  28.   sock1.OnStatus := @OnStatus;
  29.   sock1.CreateSocket;
  30.   sock1.bind('0.0.0.0', '1985'); // use the SAME outgoing port
  31.   sock1.Connect(eIp, ePort);
  32.   sock1.SendString('Re: ' + Value + #13 + #10);
  33.   sock1.Free;
  34.   Memo1.Lines.Add('---');
  35.  
  36. end;
  37.  
  38. procedure TForm1.OnStatus(Sender: TObject; Reason: THookSocketReason; const Value: String);
  39. var
  40.   sReason : String;
  41. begin
  42.   case Reason of
  43.     HR_ResolvingBegin : sReason := 'HR_ResolvingBegin';
  44.     HR_ResolvingEnd : sReason := 'HR_ResolvingEnd';
  45.     HR_SocketCreate : sReason := 'HR_SocketCreate';
  46.     HR_SocketClose : sReason := 'HR_SocketClose';
  47.     HR_Bind : sReason := 'HR_Bind';
  48.     HR_Connect : sReason := 'HR_Connect';
  49.     HR_CanRead : sReason := 'HR_CanRead';
  50.     HR_CanWrite : sReason := 'HR_CanWrite';
  51.     HR_Listen : sReason := 'HR_Listen';
  52.     HR_Accept : sReason := 'HR_Accept';
  53.     HR_ReadCount : sReason := 'HR_ReadCount';
  54.     HR_WriteCount : sReason := 'HR_WriteCount';
  55.     HR_Wait : sReason := 'HR_Wait';
  56.     HR_Error : sReason := 'HR_Error';
  57.   end;
  58.   Memo1.Lines.Add(sReason + ' ' + Value);
  59. end;

On the controller you press button1 to begin listening.
On the client you press button1 to let the client listen and send a string to the controller.
The controller uses the eIp and ePort to send the string back.
Weird thing is that I forwarded port 9090 to another computer and I still get the string back from the controller. Even when I opened a whole new UDP socket. So maybe the router still uses the same UDP port for the cIP:cPort combination.

I haven't tested it with a third computer (second client) yet.
(need to figure out how to do that with two networks  %) )

Result on controller side is:
Code: [Select]
HR_ResolvingBegin 0.0.0.0:1985
HR_ResolvingEnd 0.0.0.0:1985
HR_SocketCreate IPv4
HR_Bind 0.0.0.0:1985
HR_CanRead
HR_ReadCount 14
recv: testtesttest
80.80.80.80 : 9090
HR_SocketClose
HR_ResolvingBegin 0.0.0.0:1985
HR_ResolvingEnd 0.0.0.0:1985
HR_SocketCreate IPv4
HR_Bind 0.0.0.0:1985
HR_ResolvingBegin 80.80.80.80:9090
HR_ResolvingEnd 80.80.80.80:9090
HR_Connect 80.80.80.80:9090
HR_WriteCount 18
HR_SocketClose
---

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #39 on: November 19, 2020, 11:23:14 am »
Sorry I don't understand what your problem is. You send from port 9090 and then wait for an answer from port 9090.
So your controller rightly writes that it received the message from

80.80.80.80: 9090

What's the problem? I do not understand
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #40 on: November 19, 2020, 11:40:56 am »
Sorry I don't understand what your problem is. You send from port 9090 and then wait for an answer from port 9090.
So your controller rightly writes that it received the message from

80.80.80.80: 9090

What's the problem? I do not understand
The problem is that on my router, I have UDP port 9090 forwarded to another computer.
So, actually NOBODY should be able to send an UDP packet to my 80.80.80.80:9090 and that it reaches my computer.

But maybe my router records those IP:PORT combinations and reroutes 9090 temporary to my computer instead of the other.
But I can't test this because for testing I would need 3 network environments.

You can see with my code if the messages gets back from the controller.
You could hard-code a second client that tries to send multiple messages to the first client IP:PORT.
Then in the first client software try to code outgoing message to the second client and see if the first (or second) receives a messages.

But my advice is... keep the example simple (to first determine if punching is really possible).

Maybe I have access to another network tomorrow to test this.

Edit:
I tried this code https://gist.github.com/somic/224795#file-udp_hole_punch_tester-py
Using the same port on both sides and without one publicly accessible, the hole is punched on that port.
So it should work...
« Last Edit: November 19, 2020, 11:46:28 am by rvk »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #41 on: November 19, 2020, 11:57:49 am »
But UDP broadcasts don't use connections. Therefore the port can be used simultaneously by several programs. At least I seem to remember that this is the case.

I looked at the test you used, but it's in python. I do not know him. Can you turn it into pascal? So I understand what it does?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #42 on: November 19, 2020, 12:08:13 pm »
But UDP broadcasts don't use connections. Therefore the port can be used simultaneously by several programs. At least I seem to remember that this is the case.
Yes, but you can forward UDP packages on a router. In that case UDP packages should always go there. But somehow the router is ignoring that.

I translated the code to some simple Lazarus example.

Put this code on both sides and change line 2 and 3 for external IP of client 1 and 2.
And change line 16 and 19 to show a different message and use the other IP on the second client.

For me it worked perfectly on a port which isn't public on both sides. So it shows that the hole is really punched because both ends receive the WE HAVE CONTACT message and could communicate afterwards (without udp port forwarding on either side).

Code: Pascal  [Select][+][-]
  1. const
  2.   myClient1 = '84.84.84.84';
  3.   myClient2 = '80.80.80.80';
  4.   myPort = '9099'; // some port which is NOT public on BOTH ends to show the hole is punched
  5.  
  6. procedure TForm1.Button1Click(Sender: TObject);
  7. var
  8.   sock1: TUDPBlockSocket;
  9.   Value: ansistring;
  10. begin
  11.  
  12.   sock1 := TUDPBlockSocket.Create;
  13.   sock1.OnStatus := @OnStatus;
  14.   sock1.CreateSocket;
  15.   sock1.bind('0.0.0.0', myPort);
  16.   sock1.Connect(myClient2, myPort); // change this to 1 on the other client
  17.   while True do
  18.   begin
  19.     Value := 'Hey there 2'; // change this to 1 on the other client
  20.     sock1.SendString(Value + #13 + #10);
  21.     Memo1.Lines.Add('send: ' + Value);
  22.     if sock1.CanRead(1000) then
  23.     begin
  24.       Value := sock1.RecvString(500);
  25.       Memo1.Lines.Add('recv: ' + Value);
  26.       sock1.SendString('WE HAVE CONTACT' + #13 + #10);
  27.       if Value = 'WE HAVE CONTACT' then break;
  28.     end;
  29.     Application.ProcessMessages;
  30.   end;
  31.   sock1.Free;
  32.  
  33. end;
  34.  
  35. procedure TForm1.OnStatus(Sender: TObject; Reason: THookSocketReason; const Value: String);
  36. var
  37.   sReason : String;
  38. begin
  39.   case Reason of
  40.     HR_ResolvingBegin : sReason := 'HR_ResolvingBegin';
  41.     HR_ResolvingEnd : sReason := 'HR_ResolvingEnd';
  42.     HR_SocketCreate : sReason := 'HR_SocketCreate';
  43.     HR_SocketClose : sReason := 'HR_SocketClose';
  44.     HR_Bind : sReason := 'HR_Bind';
  45.     HR_Connect : sReason := 'HR_Connect';
  46.     HR_CanRead : sReason := 'HR_CanRead';
  47.     HR_CanWrite : sReason := 'HR_CanWrite';
  48.     HR_Listen : sReason := 'HR_Listen';
  49.     HR_Accept : sReason := 'HR_Accept';
  50.     HR_ReadCount : sReason := 'HR_ReadCount';
  51.     HR_WriteCount : sReason := 'HR_WriteCount';
  52.     HR_Wait : sReason := 'HR_Wait';
  53.     HR_Error : sReason := 'HR_Error';
  54.   end;
  55.   Memo1.Lines.Add(sReason + ' ' + Value);
  56. end;

Code: [Select]
HR_ResolvingBegin 0.0.0.0:9099
HR_ResolvingEnd 0.0.0.0:9099
HR_SocketCreate IPv4
HR_Bind 0.0.0.0:9099
HR_ResolvingBegin 80.80.80.80:9099
HR_ResolvingEnd 80.80.80.80:9099
HR_Connect 80.80.80.80:9099
HR_WriteCount 13
send: Hey there 2
HR_WriteCount 13
send: Hey there 2
HR_WriteCount 13
send: Hey there 2
HR_WriteCount 13
send: Hey there 2
HR_CanRead
HR_ReadCount 13
recv: Hey there 1
HR_WriteCount 17
HR_WriteCount 13
send: Hey there 2
HR_CanRead
HR_ReadCount 17
recv: WE HAVE CONTACT
HR_WriteCount 17
HR_SocketClose


xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #43 on: November 21, 2020, 09:57:13 am »
I have changed your code slightly.

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes, SysUtils, CustApp, blcksock
  10.   { you can add units after this };
  11.  
  12. type
  13.  
  14.   { TMyApplication }
  15.  
  16.   TMyApplication = class(TCustomApplication)
  17.   protected
  18.     procedure DoRun; override;
  19.   public
  20.     constructor Create(TheOwner: TComponent); override;
  21.     destructor Destroy; override;
  22.     procedure WriteHelp; virtual;
  23.     procedure RunCode(myClient, myPort: string);
  24.     procedure OnStatus(Sender: TObject; Reason: THookSocketReason; const Value: String);
  25.  
  26.   end;
  27.  
  28. { TMyApplication }
  29.  
  30. procedure TMyApplication.DoRun;
  31. var
  32.   ErrorMsg : String;
  33.   client1  : string;
  34.   myport   : string;
  35. begin
  36.   // quick check parameters
  37.   ErrorMsg:=CheckOptions('h', 'help');
  38.   if ErrorMsg<>'' then begin
  39.     ShowException(Exception.Create(ErrorMsg));
  40.     Terminate;
  41.     Exit;
  42.   end;
  43.  
  44.   // parse parameters
  45.   if HasOption('h', 'help') then begin
  46.     WriteHelp;
  47.     Terminate;
  48.     Exit;
  49.   end;
  50.  
  51.   { add your program here }
  52.   write('Insert remote ip:');
  53.   readln(client1);
  54.  
  55.   write('Insert myport:');
  56.   readln(myport);
  57.  
  58.   RunCode(client1, myport);
  59.  
  60.   // stop program loop
  61.   Terminate;
  62. end;
  63.  
  64. constructor TMyApplication.Create(TheOwner: TComponent);
  65. begin
  66.   inherited Create(TheOwner);
  67.   StopOnException:=True;
  68. end;
  69.  
  70. destructor TMyApplication.Destroy;
  71. begin
  72.   inherited Destroy;
  73. end;
  74.  
  75. procedure TMyApplication.WriteHelp;
  76. begin
  77.   { add your help code here }
  78.   writeln('Usage: ', ExeName, ' -h');
  79. end;
  80.  
  81. procedure TMyApplication.RunCode(myClient, myPort: string);
  82. var
  83.   sock1: TUDPBlockSocket;
  84.   Value: ansistring;
  85. begin
  86.   sock1 := TUDPBlockSocket.Create;
  87.   sock1.OnStatus := @OnStatus;
  88.   sock1.CreateSocket;
  89.   sock1.bind('0.0.0.0', myPort);
  90.   sock1.Connect(myClient, myPort);
  91.   while True do
  92.   begin
  93.     Value := 'Hello : ' + myClient;
  94.     sock1.SendString(Value + #13 + #10);
  95.     writeln('send: ' + Value);
  96.     if sock1.CanRead(1000) then
  97.     begin
  98.       Value := sock1.RecvString(500);
  99.  
  100.       writeln('recv[' , sock1.GetRemoteSinIP, ':', sock1.GetRemoteSinPort , ']: ' + Value);
  101.       sock1.SendString('WE HAVE CONTACT' + #13 + #10);
  102.       if Value = 'WE HAVE CONTACT' then break;
  103.     end;
  104.   end;
  105.   sock1.Free;
  106. end;
  107.  
  108. procedure TMyApplication.OnStatus(Sender: TObject; Reason: THookSocketReason;
  109.   const Value: String);
  110. var
  111.   sReason : String;
  112. begin
  113.   case Reason of
  114.     HR_ResolvingBegin : sReason := 'HR_ResolvingBegin';
  115.     HR_ResolvingEnd : sReason := 'HR_ResolvingEnd';
  116.     HR_SocketCreate : sReason := 'HR_SocketCreate';
  117.     HR_SocketClose : sReason := 'HR_SocketClose';
  118.     HR_Bind : sReason := 'HR_Bind';
  119.     HR_Connect : sReason := 'HR_Connect';
  120.     HR_CanRead : sReason := 'HR_CanRead';
  121.     HR_CanWrite : sReason := 'HR_CanWrite';
  122.     HR_Listen : sReason := 'HR_Listen';
  123.     HR_Accept : sReason := 'HR_Accept';
  124.     HR_ReadCount : sReason := 'HR_ReadCount';
  125.     HR_WriteCount : sReason := 'HR_WriteCount';
  126.     HR_Wait : sReason := 'HR_Wait';
  127.     HR_Error : sReason := 'HR_Error';
  128.   end;
  129.   writeln(sReason + ' ' + Value);
  130. end;
  131.  
  132. var
  133.   Application: TMyApplication;
  134. begin
  135.   Application:=TMyApplication.Create(nil);
  136.   Application.Title:='My Application';
  137.   Application.Run;
  138.   Application.Free;
  139. end.
  140.  

And it works correctly. This just doesn't solve my problem. Because this code works on two hosts (one of which without NAT) whose ip address and port are known. I have to go through the controller and two clients behind NAT. The case history is completely different.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #44 on: November 21, 2020, 10:14:41 am »
And it works correctly. This just doesn't solve my problem. Because this code works on two hosts (one of which without NAT) whose ip address and port are known. I have to go through the controller and two clients behind NAT. The case history is completely different.
No no... I tried this with both hosts behind a NAT and no forwarded ports.

The only thing is that they need to know each others ip:port. But (only) that's what the controller is for.

A contacts C to make contact with B.
C sends an invite to B.
B answers, ok.
C can transmit the ip:port of A to B (or already has with the invite)
C can transmit the ip:port of B to A
Now A and B can send several UDP packages to the other with the known ports.
(That last step is what this piece of code does just to prove hole punching worked)
And if all goes well the hole is punched and they start seeing echo others messages.

(Note that the first few messages could get lost until the other side also starts sending the messages.)
« Last Edit: November 21, 2020, 10:17:45 am by rvk »

 

TinyPortal © 2005-2018