Communication between applications using socket through UDP making Multicast

Asked

Viewed 5,867 times

5

I’m trying to communicate between applications where one of them transmits a certain message and the others just receive, I don’t know the IP address of the ones that will receive and even if they won’t be there to receive the message, I just need to do a multicast on the net.

I’m using Ararat Synapse with the class TUDPBlockSocket and found the following example on the component website...

Receiving the message

procedure TForm1.btnReceberClick(Sender: TObject);
var
   rcvsock:TUDPBlockSocket;
   buf:string;
begin
  rcvsock:=TUDPBlockSocket.Create;
  try
    rcvsock.createsocket;
    rcvsock.Bind('0.0.0.0','22401');
    rcvsock.AddMulticast('234.5.6.7');
    buf:=rcvsock.RecvPacket(60000);
    showmessage(buf);
  finally
    rcvsock.free;
  end;
end;

Sending the message

procedure TForm1.btnEnviarClick(Sender: TObject);
var
  sndsock:TUDPBlockSocket;
begin
  sndsock:=TUDPBlockSocket.Create;
  try
    sndsock.createsocket;
    sndsock.Bind('0.0.0.0','0');
    sndsock.MulticastTTL := 1;
    sndsock.connect('234.5.6.7','22401');
    sndsock.SendString('Ahoy!'+CRLF);
  finally
    sndsock.free;
  end;
end;

This all works fine if opening only 2 instances of the application and at first click bo button btnReceber and on the second click the button btnEnviar. However, I open 3 instances, one sending and the other two receiving only one receives and the other is standing there waiting for the 60000 milliseconds. The test with only two instances works only if both are running on the same micro, I even checked if my router was enabled to allow the multicast, but it still didn’t work through the network.

I’m using Delphi XE and did tests on Windows XP on a VM with Virtual Box and also on a micro with Windows 7.

  • It’s been a long time (even) since I programmed in Delphi, so I don’t even risk an answer. But maybe the problem is in bind using 0.0.0.0. Have you tried using the external address of your network interface? This thread can help you understand what I mean: http://stackoverflow.com/questions/7556811/why-bind-a-socket-to-an-address

  • 1

    Do you really need multicast? If it is in the same subnet, it would be enough to use simple UDP broadcast (address 192.168.0.255 on a 192.168.0.0/24 network, for example, or 10.255.255.255 on a 10.0.0.0/8 network)

2 answers

2

Hello,

I don’t know much about Lphi but I’ve worked a lot with multicast in C so I’ll give my pinch...

Are you testing with 3 instances on the same machine? How did you get the two client instances to do the "bind" on the same port? The second should give some error in the bind (something like "address already in use") since normally you do not have 2 processes "listening" the same port.

It would be useful to test the return of the bind() function to see if it actually worked.

  • 1

    Really you are right, I did the test by checking the socket Lasterror and it showed "Address already in use". In a multicast wouldn’t it be normal for more than one process to hear the same door? I also tested with an instance on each micro but there neither worked, IE, the instance listening to the door did not get the message, I checked the router and the IGMP was enabled, have idea of what I can be?

  • I’m not sure since I always use on but of a machine but the setsockopt SO_REUSEPORT option should help. Another idea would be to use a Sniffer like wireshark to confirm that the package is exiting to the network and with the correct addresses.

2

Try using Indy components like Tidudpserver and Tidudpclient

on receipt you treat so:

procedure TMainHost.UDPServer2UDPRead(AThread: TIdUDPListenerThread;
  AData: TBytes; ABinding: TIdSocketHandle);
begin
//

//onde AData é o recebimento em bytes... 
//Você pode tratar os caracteres e montar sua mensagem com o Chr...

end;

in shipping you treat so for example:

function TMainHost.DoSendModificarCamera(
  aCamera: TCameraJSONRecognized): Integer;
var
  strTemp: String;
begin


  strTemp := 'string de envio';

  try

    IdUDPClient1.Host := '255.255.255.255';
    IdUDPClient1.Port := 34567;
    IdUDPServer2.Active := False;
    IdUDPServer2.DefaultPort := 34567;
    IdUDPClient1.Active := True;
    IdUDPClient1.Send(strTemp);
    IdUDPClient1.Active := False;
    IdUDPServer2.Active := True;
    Result := Length(x);
  except
    Result := -Length(x);
  end;

end;
  • I took the test as you suggested, although this way seems to me to be a brodcast. I had some problems with the UDP Server Read event and Delphi XE but I managed to get around it. The problem is that when trying to send the message (using two instances on the same micro) the 10013 error occurs, I have already disabled the firewaal but not solved (there is no anti virus running). Do you have any idea how to get around this problem?

  • This is not happening because you are using two UDP instances with the same port not? For example a server using this port and a client trying to connect to the server through the same port on the same PC? Try to run the server on another machine and send a message to it... because it seems to me that, the use of two apps on the same port...

  • No, the 10013 error message occurs even running an instance on each micro with firewall disabled.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.