SUMMARY:Socket Programming in Solaris 2.6 update

From: Conner McCleod (nimrha@hotmail.com)
Date: Wed Sep 16 1998 - 17:03:38 CDT


FYI,
Since posting the first Summary I received additional information. It
seems that if you are using inetd, then you don't need to worry about
socket programming since inetd handles all the socket stuff for you:

Bryan Blackburn <blb@rmi.net>
Since you've setup your server to go through inetd, you don't
need to have it worry about any socket programming; inetd will do that
for you. With inetd, you just have your server use stdin/stdout to talk
through the socket, which reduces your server script to:

$| = 1; # Or autoflush STDOUT 1...

while (<STDIN>) {
chomp;
print scalar(reverse($_)), "\r\n";
}

Also, thanks to: "David Evans" <DJEVANS@au.oracle.com>

The socket version was presented below.
Later...

Thanks to:
Robert G. Ferrell
Frank Fiamingo - Col
Russ Poffenberger
Bill Hathaway
Charles Best
John Bradley
Michael Kriss
Robert G. Ferrell
John Berninger

The solution and code are presented below. The server program can be
terminated... with ^C or killed and the port is recycled/. I can now
concentrate on the rest of the program... wich will send a start signal
on that port from a VAX machine to a SPARC20 which runs a set of EMC
disks. The server in turn will return a completed signal to the VAX
workstation. Thanks to all the people and their prompt responses.

Frank Fiamingo - Columbus <frank.fiamingo@ssds.com>... sugested that I
kill the inetd daemon with:
kill -HUP `ps -e|grep -w inetd|awk '{print $1}'`
After doing this the server program worked. However, everytime that I
kill the program... it would take serveral minutes for the socket to be
released by the OS (ndd variable).

THE FIXED SERVER CODE:
"Robert G. Ferrell" <rferrell@usgs.gov>
I don't see anything wrong with either of the config files, so
long as the server doesn't require any command line arguments like the
client does. The first thing I would try is adding a socket option to
allow
reuse of the port (just in case something is grabbing it):

#!/usr/local/bin/perl
#THIS IS THE SERVER
use strict;
use Socket;
use FileHandle;

my $port = shift || 9876;

socket (SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]);

setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die
"Setsockopt error: $!\n";

bind (SOCKET, pack('Sna4x8', AF_INET, $port, "\0\0\0\0")) || die
"Can't bind to port $port!"; listen (SOCKET, 5);

NEW_SOCKET->autoflush();
SOCKET->autoflush();

while (1) {accept(NEW_SOCKET, SOCKET);
while (<NEW_SOCKET>) {chomp; print NEW_SOCKET scalar(reverse($_)),
"\r\n"; }
}

I am suspecting that what so many of you said about not needing entries
on /etc/inetd.conf is true. I removed the entry for server1 from
inetd.conf and restarted inetd daemon with a -HUP; Then I started the
server program (with the fixed presented below). The server program
works fine without an entry in the inetd.conf file:

poffen@San-Jose.ate.slb.com (Russ Poffenberger)...
"The reason why is because of the way inetd works. Inetd is already
bound to the port, so you can't bind to it again. There is no need,
however, because inetd will hand you off a socket already connected to
the requestor. This socket is the file descriptor 0 (stdin)...
You may have been able to get it running briefly after sending
HUP to inetd since it will have released all ports and taken a few
seconds to re-initialize. inetd will keep the port bound. You do not
need to create a socket, bind or listen to it. inetd has already done
all that for you. Pretty much all you need to do is use FD 0 as your
socket file descriptor."

Bill Hathaway <wdh@poss.com>
you don't actually say what your error is, but I'm guessing
that it seems your server is not listening to the port. It looks like
your server tries to listen on a port using bind(), but if you are
trying to run from inetd, inetd does all the bind() stuff for you, and
hands you the connected socket as stdin/stdout. So I'd either
A) use your program as is, but not run it from inetd
B) take out all the network specific code from your program,
have it launched from inetd and have it read/write stdin/out
If you want to verify that inetd works that way, try replacing
the madserver inetd line with one that launches /usr/bin/cat, telnet
to it, then type a few things and hit return.

John Berninger <jberninger@bbtnet.com>
I'm not sure if this will help, but here goes... I just did
some real quick-and-dirty socket type 'research'... Took a
script I'd written using STDIN and put in entries for it in the
inetd.conf and services files. Then I telnet'ed to the port
port I'd set it for in services, and put in a line of text. The
program took the socket input from the telnet session as STDIN,
I didn't need to bind to any sockets. What I think (and this is only a
WAG based on that limited experiment) is that when you telnet to the
port, it starts one instance of the script and binds it to your port,
then you attempt to re-bind the port within the script, causing an
error. You might want to try removing the bind commands and such and
just take in STDIN at the server side unless you can launch it
as a daemon and remove the bindings in /etc/services and
/etc/inetd.conf.
                

Conner.

Ps. Yes, I'll read up on the RPC from O'Reilly and TCP/IP Second
edition from Stevens.

ORIGINAL E-MAIL:

This is a Solaris Question (for those fanatics that belive in the purity
of the Mailing list):

I am writing a socket under Solaris 2.6 (SPARC20) using perl 5.004_4.
The server and client workstation are the same.

I have defined the entries for the server portion of the inetd.conf
file:
"server1 stream tcp nowait root /opt/socket_prg/server
server1"
Where server1 is the socket /opt/socket_prg/server is the full path to
the socket program (in perl).

I also added the port under /etc/services:
"server1 9876/tcp # madserver"
I been debudding by telneting to the port "telnet server 9876". I also
have been using "perl -d server" to debug the program. I don't believe
that there is something wrong with the programs. They are copied from
documented and tested samples in literature. I am incline to belive
that it is something that I am defining wrong in the /etc/inetd.conf or
/etc/services. Can someone point out to me the proper way to create
entries in these files... if the files are wrong. I have included the
server and client programs that I am using.

If my errors are not on the files... but in the code; please be
especific as to the changes.

Conner

#!/usr/local/bin/perl
#THIS IS THE SERVER
use strict;
use Socket;
use FileHandle;

my $port = shift || 9876;

socket (SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]);
bind (SOCKET, pack('Sna4x8', AF_INET, $port, "\0\0\0\0"))
       || die "Can't bind to port $port!";
listen (SOCKET, 5);

NEW_SOCKET->autoflush();
SOCKET->autoflush();

while (1) {
    accept(NEW_SOCKET, SOCKET);
    while (<NEW_SOCKET>) {
        chomp;
        print NEW_SOCKET scalar(reverse($_)), "\r\n";
    }
}

#!/usr/local/bin/perl
#THIS IS THE CLIENT
use Socket;
use FileHandle;

# Command-line arguments: the server's port and the server's name.
($port, $server) = @ARGV;
$port && $server or die "Please supply both port and server.";

socket (SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]);
connect (SOCKET, pack('Sna4x8', AF_INET, $port,
(gethostbyname($server))[4]))
   || die "Can't connect to server $server on port $port.\n";

SOCKET->autoflush();

$pid = fork;

if ($pid == 0) { print STDOUT while (<SOCKET>); } # Read from the
server
else { print SOCKET while (<STDIN>); close SOCKET; exit} #
Write to the server

______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:12:49 CDT