Recycling some code I wrote in 2004 for just this purpose. Implemented on Windows (Tested with Active perl). Hope it helps. And yes, IO::Socket works fine on Win32.
############################################## # UDP Relay # March 2004, by Netwallah # This program can be used as a Client, server, or Relay # for UDP packets. # In CLIENT mode, it sends whatever is keyed in to a Dest UDP IP:Port # In SERVER mode, it receives packets on a port. # In RELAY mode, it receives packets, and forwards them to a different + IP:port. # UDP only. # --How to Run --- # perl UDPRelay <Mode> <Params> # <Mode> is one of C S or R # In Client mode, Params are <Dest IP> and <Dest-port> # In Server mode, Params are a list of ports to listen on # In Relay mode, Params are [<listen-port> <Dest IP> <Dest-port>] ... # # It can relay multiple ports with a single instance. ############################################### use strict; use warnings; use IO::Socket; use IO::Select; my $MAX_TO_READ = 1024; my $ClientServer = shift or die "Please specify CLIENT SERVER or RELAY + mode"; my ($datagram,$flags,$dest_port,$dest_addr,$send_socket, %Conversation); $| = 1; # autoflush STDOUT if ($ClientServer =~m/^c/i){ #----- Client ---------- $dest_addr = shift or die "Dest addr required for Client"; $dest_port = shift or die "dest port required for Client"; # Need ex +tra param $send_socket=Make_Send_Socket($dest_addr,$dest_port); Send_Msgs(); # Send_and_Rcv_Forked(); }elsif ($ClientServer =~m/^s/i){ # Server ------- Rcv_Msgs(\&Msg_Handler,1,\@ARGV); }else{ ## We are a RELAY --- ------------------------ #Relay comes in triplets - ListenPort, DestAddr, DestPort my (@ListenAddrs, @SendSockets);; while (my $listen=shift){ $dest_addr = shift or die "Dest addr required for relay"; $dest_port = shift or die "dest port required for RELAY"; # Need e +xtra param push @SendSockets, # $Relay{$listen}{SENDSOCKET} = $Conversation{$listen}{SERVSOCKET} = Make_Send_Socket($dest_addr,$dest_port); push @ListenAddrs,$listen; $Conversation{$listen}{SERVIP} =$dest_addr; $Conversation{$listen}{SERVPORT} =$dest_port; } Rcv_Msgs(\&Relay_Handler,0,\@ListenAddrs,\@SendSockets); } ########################################### sub Make_Send_Socket { my ($dest_addr,$dest_port) = @_; my $send_socket = IO::Socket::INET->new( PeerPort => $dest_port, PeerAddr => $dest_addr, Proto => "udp") or die "Couldn't be a udp Sender to $dest_addr on port $dest_por +t : $@\n"; return $send_socket; } ################################ sub Send_Msgs{ print "I am the Client - please enter data to send to $dest_addr on + port $dest_port:\n"; $dest_addr or die "Dest IP not specified\n"; while (<>){ chomp; m/quit/i and exit 0; #send SOCKET,MSG,FLAGS,TO length($_) and $send_socket->send ($_); sleep .2; # Wait for response... #if (IO::Select->select ( [$send_socket], undef, undef , 2 )) +{ # check for response print "RCV:" . read_socket($send_socket, $datagram) . "\ +n"; #} } exit; } ####################################### sub Send_and_Rcv_Forked{ # Broken print "I am the Forked Client - please enter data to send to $dest_ +addr on port $dest_port:\n"; $dest_addr or die "Dest IP not specified\n"; defined(my $child = fork) or die "fork() failed: $!"; if ($child == 0){ #Child process while (my $data=read_socket($send_socket, $datagram)){ print "RCV $data\n"; } exit; }else{ print "Parent here ..Child=$child \n"; while (<>){ chomp; m/quit/i and exit 0; #send SOCKET,MSG,FLAGS,TO $send_socket->send ($_); } }; } ####################################### sub Rcv_Msgs{ my $handler_sub = shift; my $Echo_Request = shift; # Does he want us to Echo ? my @PortList = @{shift()} or die "Please specify one or more ports t +o listen on"; my @ExtraHandles = @{shift() || []}; # Existing handles to listen on +. my $Socket_Selector = IO::Select->new(); my @readyHandles; my %SockHandle_To_Port; # Setup all receive sockets and selector foreach my $port (@PortList){ my $handle = IO::Socket::INET->new( LocalPort => $port, Proto => "udp") or die "Couldn't be a udp Listener on port $port : $@\n"; $Socket_Selector->add($handle); $SockHandle_To_Port{$handle} = $port; # Next line required for RELAY operation... $Conversation{$Conversation{$port}{SERVPORT}}{CLIENTSOCKET} = $han +dle; } # Throw in the STDIN ... ## $Socket_Selector->add(\*STDIN); # Does not work on Win32 # We also listen on the extra handles... foreach(@ExtraHandles){ $Socket_Selector->add($_); #Hmm - how do we associate these with what we sent ? } print "I am the SERVER ====Go into a loop receiving messages:\n"; #while (my $Sender_Info = $rcv_socket->recv($datagram, $MAX_TO_READ, + $flags)) { while(@readyHandles = $Socket_Selector->can_read){ foreach my $h (@readyHandles){ # Find Port corresponding to handle.... my $rcvport = $SockHandle_To_Port{$h} || 0; my ( $Sender_addr, $Sender_port, $datagram) = read_socket($ +h); &$handler_sub($Sender_addr, $Sender_port, $datagram,$rcvport +); $Echo_Request and Process_Echo_And_commands($Echo_Request,$h +,$datagram); # ECHO it } } } ############################### sub read_socket{ my $h = shift; # Socket Handle my ($datagram,$flags); my $Sender_Info = $h->recv($datagram, $MAX_TO_READ, $flags) or ret +urn 0; my ($Sender_port, $Sender_iaddr_binary) = sockaddr_in($Sender_Info +); my $Sender_addr = inet_ntoa($Sender_iaddr_binary); return $Sender_addr, $Sender_port, $datagram; } ############################### sub Msg_Handler{ my ($peer_addr, $port, $datagram,$rcvport) = @_; print "Rcv $rcvport from $peer_addr:$port \t:$datagram\n"; } ################################## sub Process_Echo_And_commands{ my ($Options,$sock,$Msg) = @_; $sock->send("ECHO:$Msg"); #Handle any recognized commands.. if ($Msg =~m/^CMD\s+(.+)/){ my $result = `$1`; print "\t$1:$result\n"; $sock->send($result) } } ################################## sub Relay_Handler{ Msg_Handler(@_); # Print it first .. No parsing my ($sender_addr, $Sender_port, $datagram,$rcvport) = @_; #my $output_handle = $Relay{$rcvport}{SENDSOCKET}; my $output_handle = $Conversation{$rcvport}{SERVSOCKET}; if ($rcvport == 0){#This is a response that needs to return to clie +nt.. #Send it to Sender_port's handle #print "--Relaying Server response to orig client for $Sender +_port:$datagram\n"; $output_handle = $Conversation{$Sender_port}{CLIENTSOCKET}; } $output_handle->send($datagram); # Relay it }

     ..to maintain is to slowly feel your soul, sanity and sentience ebb away as you become one with the Evil.


In reply to Re: UDP Server on Win32 by NetWallah
in thread UDP Server on Win32 by mpapet

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.