Forum > Networking and Web Programming
Easiest way to send UDP packets
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