SarvaiD has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to build a perl application using the SCTP transport, and am having problems receiving any packets/messages from the socket. I've tried to connect, listen, rcvmsg, and nothing produces output to screen. I know SCTP support hasn't been around for too long, and searching this site only produces one other question.... Maybe someone has more info on using it? I'm running ActivePerl 5.10 on a Solaris 10 Intel platform. Here is the script.
#!/opt/ActivePerl-5.10/bin/perl -U use Socket; $port = 5002; $iaddr = inet_aton('localhost'); $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname('sctp'); socket( Server, AF_INET, SOCK_STREAM, $proto ) || die "Socket Failed: +$!"; bind(Server, $paddr) || die "Socket Bind Failed: $!"; listen(Server, SOMAXCON) || die "Socket Listen Failed: $!"; print "SERVER started on SCTP port $port\n"; while (1) { recvmsg(Sock, $MSG, 1024, MSG_WAITALL) || die "Socket Recieve Fai +led: $!"; print "Packet: ". $MSG ."\n"; }

Replies are listed 'Best First'.
Re: SCTP Protocol Support
by zentara (Cardinal) on Apr 09, 2008 at 19:43 UTC
    Just a guess, without testing.... are you using "accept" and "select"? Look at this code where it accepts connections.
    #!/usr/bin/perl use strict; #use warnings ; use Socket; my $proto = getprotobyname('tcp'); my $port = 4444; # Create 'sockaddr_in' structure to listen to the given port # on any locally available IP address my $servaddr = sockaddr_in($port, INADDR_ANY); # Create a socket for listening on socket SERVER, PF_INET, SOCK_STREAM, $proto or die "Unable to create socket: $!"; # bind the socket to the local port and address bind SERVER, $servaddr or die "Unable to bind: $!"; # listen to the socket to allow it to receive connection requests # allow up to 10 requests to queue up at once. listen SERVER, 10; # now accept connections print "Server running on port $port...\n"; while (accept CONNECTION, SERVER) { select CONNECTION; $| = 1; select STDOUT; print "Client connected at ", scalar(localtime), "\n"; print CONNECTION "You're connected to the server!\n"; while (<CONNECTION>) { print "Client says: $_\n"; print CONNECTION $_; } close CONNECTION; print "Client disconnected\n"; }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: SCTP Protocol Support
by mr_mischief (Monsignor) on Apr 09, 2008 at 20:17 UTC
    As zentara says, SCTP being a connection-oriented rather than packet-oriented transport matters. Like TCP, a server must accept a connection in order to read from it or write to it. This is despite the fact that many people bill SCTP as "UDP-like" because it deals in messages instead of byte streams and that messages can be conditionally processed out of order.
      Thanks for the replies. I tried the suggested changes, which didn't help. Adding a print statement after the "Accept" loop shows the script will listen, but not accept a connection. I have verified that the server listens on port SCTP/5002 using a "netstat -an". I'm also learning/writing/testing a C program in parallel, and C can open the same port and responds to the SCTP requests.
      #!/opt/ActivePerl-5.10/bin/perl -U use Socket; $port = 5002; $iaddr = inet_aton('localhost'); $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname('sctp'); socket( Server, AF_INET, SOCK_STREAM, $proto )|| die "Socket Failed: $ +!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "se +tsockopt: $!"; bind(Server, $paddr) || die "Socket Bind Failed: $!"; listen(Server, SOMAXCON) || die "Socket Listen Failed: $!"; print "SERVER started on SCTP port $port\n"; while (accept CONNECTION, Server) { print "Connection Accepted\n"; select CONNECTION; $| = 1; select STDOUT; print "Client connected at ", scalar(localtime), "\n"; print CONNECTION "You're connected to the server!\n"; while (<CONNECTION>) { print "Client says: $_\n"; print CONNECTION $_; } close CONNECTION; print "Client disconnected\n"; }
        I haven't worked much with SCTP -- nothing beyond toy programs.

        Your code (in Re: SCTP Protocol Support) works for me using Strawberry 5.10 on XP including the setsockopt. My Linux box at home still has 5.8.7, and I get an error about SCTP not being supported. I can try the code on a more recent Linux distro with a more recent perl tomorrow at the office if I don't get around to upgrading at home tonight.

        Update: I got your code to work on perl 5.10.0 and 5.8.7 on my Mandriva 2006.0 box by changing out the $proto as returned by getprotobyname for the constant IPPROTO_SCTP in the fourth argument position for socket as one would in C. I guess this particular system isn't up to getting the protocol by its name.

        #socket( Server, AF_INET, SOCK_STREAM, $proto )|| die "Socket Failed: +$!"; socket( Server, AF_INET, SOCK_STREAM, IPPROTO_SCTP )|| die "Socket Fai +led: $!";

        This is just a stab in the dark, but I remember seeing something somewhere about Perl's implementation of setsockopt not working on SCTP sockets. Searching on Google for "setsockopt Perl SCTP" to see if I could find any evidence, I found this Fedora ticket which says nothing on Fedora works with getsockopt or setsockopt for socket type SCTP, although the author of the bug report had no problems on Solaris with the same Perl source. Perhaps it's a rare Perl on Linux issue, or perhaps it's a distribution-specific issue in some distributions. Perhaps your Solaris on x86 has the same issue as Fedora, while Solaris on Sparc does not. It's hard to tell at this point.

        I hope this helps at least somewhat. I haven't taken the time to really use it yet, but SCTP does look promising.