Forum > Networking and Web Programming

Easiest way to send UDP packets

<< < (3/4) > >>

Remy Lebeau:

--- Quote from: ChrisTG on May 27, 2024, 11:57:50 am ---Then I saw that there's a ready to install version of Indy10 in the Online package installer. So I installed it.
What I'm now missing, is a hint about "how to start".

--- End quote ---

Start with the TIdUDPClient component.  Set the Host and Port properties to the desired target, then call the SendBuffer() method as needed.


--- Quote from: ChrisTG on May 27, 2024, 11:57:50 am ---The Indy-site and various resources seem to be offline meanwhile.

--- End quote ---

The site is not offline, but portions of it are broken:

https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/

ChrisTG:
Hi guys,
thank you all for your helpful replies.
I think I will start with the neat little unit Warfley created. It looks quite similar to my try. I tried to use "Winsock2" directly since there are a few C++ examples for sending UDP broadcasts in the net. My goal is to send a WOL packet. But apparently it does not work:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program udp_send; uses winsock2, sysutils, strutils, windows; function inet_pton(Family: Integer; pszAddrString: PAnsiChar; pAddrBuf: Pointer): Integer; stdcall; external 'Ws2_32.dll'; var  Sock: TSocket;  Addr: TSockAddr;  LocalAddr: TSockAddr;  LocalIP: PChar = '0.0.0.0';  HostIP: PChar = '192.168.1.255';  HostPort: Word = 7;  AString: String = chr(255) + chr(255) + chr(255) + chr(255) + chr(255) + chr(255);  MAC: String = '112233445566';  MACchr: String;  i: Integer;  WSData: TWSAData;  Optval: dword; begin  i := 1;  MACchr := '';  while i < Length(MAC) do  begin    MACchr := MACchr + chr(StrToInt('$'+MAC[i]+MAC[i+1]));    i := i + 2;  end;   MACchr := DupeString(MACchr, 16);  AString := AString + MACchr;   WSdata := Default(TWSAData);  WSAStartup(makeword(2,2), WSDATA);     LocalAddr.sin_family := AF_INET;    LocalAddr.sin_port := htons(HostPort);    inet_pton(AF_INET, LocalIP, @LocalAddr.sin_addr.s_addr);     Addr.sin_family := AF_INET;    Addr.sin_port := htons(HostPort);    inet_pton(AF_INET, HostIP, @Addr.sin_addr.s_addr);     Sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);     Optval := 1;    setsockopt(Sock, SOL_SOCKET, SO_BROADCAST, Optval, sizeof(Optval));     bind(Sock, LocalAddr, SizeOf(LocalAddr));    SendTo(Sock, AString, Length(AString), 0, Addr, SizeOf(Addr));     CloseSocket(Sock);    WSACleanup; end. Note that I defined the function inet_pton here directly as it is missing in FP's "Winsock2" unit somehow.
I found that one has to use "setsockopt" to be able to send out on broadcast-addresses, but still the broadcasts are not sent.
What am I doing wrong?

TRon:

--- Quote from: ChrisTG on May 28, 2024, 09:06:03 pm ---I think I will start with the neat little unit Warfley created. It looks quite similar to my try. I tried to use "Winsock2" directly since there are a few C++ examples for sending UDP broadcasts in the net.

--- End quote ---
Why the complicated and dependent winsock usage while Free Pascal has a (platform agnostic) sockets units ?


--- Quote ---But apparently it does not work:

--- End quote ---
It is not so apparent because the presented code fails to show/provide any error.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program clumsyexample; {$mode objfpc}{$h+} uses  sockets, sysutils; procedure Inform(condition: boolean; trues, falses: string);var  errcode: integer;  errstr : string;begin  if condition then writeln(trues) else  begin    errcode := GetLastOSError;    errstr  := SysErrorMessage(errcode);    writeln('ERROR: ', falses, ' (error code ', errcode, ' = ', errstr,')');  end;end; procedure client;var  sock       : TSocket;  optval     : int32 = 1;   remotipstr : string = '127.0.0.1';  remotport  : integer = 8888;  remotaddr  : TSockAddr;   msg        : pchar = 'hello world';  retval     : integer;begin  remotaddr.sin_family := AF_INET;  remotaddr.sin_port := htons(remotport);  remotaddr.sin_addr := StrToNetAddr(remotipstr);   sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  inform(sock <> -1, 'new socket created', 'unable to create new socket');   retval := fpsetsockopt(sock, SOL_SOCKET, SO_BROADCAST, @optval, sizeof(optval));  inform(retval <> -1, 'socket option set', 'unable to set socket option');   retval := fpsendto(sock, msg, length(msg), 0, @remotaddr, sizeof(remotaddr));  inform(retval <> -1, 'message broadcasted', 'unable to broadcast message');   retval := closesocket(sock);  inform(retval <> -1, 'socket closed', 'unable to close socket');end; procedure server;var  sock        : TSocket;   localaddr   : TSockAddr;  localport   : integer = 8888;  remotaddr   : TSockAddr;  len         : integer;  retval      : integer;  slen        : TSockLen;   buf : array[0..200] of char;begin  localaddr.sin_family      := AF_INET;  localaddr.sin_port        := htons(localport);  localaddr.sin_addr.s_addr := htonl(INADDR_ANY);   sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  inform(sock <> -1, 'new socket created', 'unable to create new socket');   retval := fpbind(sock, @localaddr, sizeof(localaddr));  inform(retval <> -1, 'bind succeeded', 'unable to bind socket');   while true do  begin    writeln('waiting for data...');    len := fprecvfrom(sock, @buf[0], sizeof(buf), 0, @remotaddr, @slen);    inform(len <> -1, 'message received', 'unable to receive message');    if len <> -1 then    begin      writeln      (        format('received message "%s" from %s:%d',        [copy(buf, 0, len), NetAddrToStr(remotaddr.sin_addr), ntohs(remotaddr.sin_port)])      );    end;  end;   retval := closesocket(sock);  inform(retval <> -1, 'socket closed', 'unable to close socket');end; begin  if (paramcount = 1) and (paramstr(1) = 'client') then  begin    writeln('start client');    client;  end  else  begin    writeln('start server');    server;  end;end. 
Windows firewall, restricted ports etc.... just to name a few things.

dseligo:

--- Quote from: TRon on May 29, 2024, 03:31:35 am ---
--- Quote from: ChrisTG on May 28, 2024, 09:06:03 pm ---I think I will start with the neat little unit Warfley created. It looks quite similar to my try. I tried to use "Winsock2" directly since there are a few C++ examples for sending UDP broadcasts in the net.

--- End quote ---
Why the complicated and dependent winsock usage while Free Pascal has a (platform agnostic) sockets units ?


--- Quote ---But apparently it does not work:

--- End quote ---
It is not so apparent because the presented code fails to show/provide any error.

--- End quote ---

You example gives error:

--- Code: Text  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---ERROR: unable to receive message (error code 10014 = The system detected an invalid pointer address in attempting to use a pointer argument in a call.)
You didn't set length of remoteaddr in slen.

This works (I only added line 73):


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program clumsyexample; {$mode objfpc}{$h+} uses  sockets, sysutils; procedure Inform(condition: boolean; trues, falses: string);var  errcode: integer;  errstr : string;begin  if condition then writeln(trues) else  begin    errcode := GetLastOSError;    errstr  := SysErrorMessage(errcode);    writeln('ERROR: ', falses, ' (error code ', errcode, ' = ', errstr,')');  end;end; procedure client;var  sock       : TSocket;  optval     : int32 = 1;   remotipstr : string = '127.0.0.1';  remotport  : integer = 8888;  remotaddr  : TSockAddr;   msg        : pchar = 'hello world';  retval     : integer;begin  remotaddr.sin_family := AF_INET;  remotaddr.sin_port := htons(remotport);  remotaddr.sin_addr := StrToNetAddr(remotipstr);   sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  inform(sock <> -1, 'new socket created', 'unable to create new socket');   retval := fpsetsockopt(sock, SOL_SOCKET, SO_BROADCAST, @optval, sizeof(optval));  inform(retval <> -1, 'socket option set', 'unable to set socket option');   retval := fpsendto(sock, msg, length(msg), 0, @remotaddr, sizeof(remotaddr));  inform(retval <> -1, 'message broadcasted', 'unable to broadcast message');   retval := closesocket(sock);  inform(retval <> -1, 'socket closed', 'unable to close socket');end; procedure server;var  sock        : TSocket;   localaddr   : TSockAddr;  localport   : integer = 8888;  remotaddr   : TSockAddr;  len         : integer;  retval      : integer;  slen        : TSockLen;   buf : array[0..200] of char;begin  localaddr.sin_family      := AF_INET;  localaddr.sin_port        := htons(localport);  localaddr.sin_addr.s_addr := htonl(INADDR_ANY);   sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  inform(sock <> -1, 'new socket created', 'unable to create new socket');   retval := fpbind(sock, @localaddr, sizeof(localaddr));  inform(retval <> -1, 'bind succeeded', 'unable to bind socket');   slen := SizeOf(remotaddr);   while true do  begin    writeln('waiting for data...');    len := fprecvfrom(sock, @buf[0], sizeof(buf), 0, @remotaddr, @slen);    inform(len <> -1, 'message received', 'unable to receive message');    if len <> -1 then    begin      writeln      (        format('received message "%s" from %s:%d',        [copy(buf, 0, len), NetAddrToStr(remotaddr.sin_addr), ntohs(remotaddr.sin_port)])      );    end;  end;   retval := closesocket(sock);  inform(retval <> -1, 'socket closed', 'unable to close socket');end; begin  if (paramcount = 1) and (paramstr(1) = 'client') then  begin    writeln('start client');    client;  end  else  begin    writeln('start server');    server;  end;end. 

marcov:

--- Quote from: Thaddy on May 28, 2024, 10:41:03 am ---I never use components for that, I use either fcl-net or synapse.

--- End quote ---

I use Indy10 in threads, so no designtime either.  I stuck with using libraris rather than rolling my own because of the asynchronous nature. Most basic socket examples are synchronous/blocking I/O.

And anyway, Linux/FreeBSD is only of secondary importance for me.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version