Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Un-initalised values in Server\Client

by eoin (Monk)
on Dec 27, 2003 at 23:40 UTC ( [id://317250]=perlquestion: print w/replies, xml ) Need Help??

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

Brethren & Sistren,

I'm back again seeking your assistance. I have recently been playing around with the IO::SOCKET module and am having some problems with it.
My plan in the long term is to a have something like icq and msn messenger etc.. but a lot less flashy with only the basic functions.
At the moment however, I am having trouble setting up a server and a client that can talk to each other let alone transfer files and chat.

My code is fairly basic as I'm only getting in to this stuff now. I have read a few articles regarding to the use of IO::SELECT in conjunction with IO::SOCKET but I'm having trouble coming to grips with IO::SOCKET so i decided to stick with it until I get it figured.
Here's my attempt at the server (its only intended for a single client at the moment)

#THE SERVER #!/usr/bin/perl -w use strict; use IO::Socket; my $port = 6941; my $auth = " " ; my $code = " " ; #PREVENT ZOMBIES $SIG{CHLD} = 'IGNORE'; #CREATE SOCKET my $listen_socket = IO::Socket::INET->new(LocalPort => $port, Listen => 10, + Proto => 'tcp', Reuse => 1); die unless $listen_socket; warn "Server ready. Waiting for connections ... \n"; #GET CONNECTIONS my $socket = $listen_socket->accept; #REQUEST AUTHORISATION print $socket "Connected to Server\n"; print $socket "Please insert auth code:\n"; #ASK FOR CODE $code = <$socket>; #GET CODE verify($code,$socket); #SEND FOR VERIFICATION exit; #SHOULD NEVER GET HERE #VERIFY AUTHORISATION CODE sub verify{ my ($code,$socket) = @_; my $auth_code = "6941"; if($code eq $auth_code) { $auth = "1"; print $socket "Accepted\n\n"; load_interface($socket); } else { $auth = "0"; print $socket "Good bye\n\n"; exit; } } sub load_interface{ my $socket = $_[0]; exit unless( $auth == "1"); open(CONFIG,"conifg") || die "Can't load config file\n"; #THIS WILL B +E A LIST OF COMMANDS my $data = " "; while(<CONFIG>) { $data = $data . $_; } print $socket $data; print $socket "\n\nWhat would you like to do (0\1\2\3\....): "; my $cmd = <$socket>; #GET COMMAND cmd($cmd,$socket); } #THIS WILL DO COMMAND. ONLY FOR TEST PURPOSES AT THE MOMENT sub cmd{ my( $cmd,$socket) = @_; exit if($cmd == "q"); print $socket "\n\nYou chose option $cmd!!!!!!\n\n"; load_interface(); }

As you can see very basic. Not very pretty. And doesn't work.
The problem that I have is when the server tries to get the authorisation $code from the client $code doesn't get set at all. And when the script tries to use it later Perl says that it is a un-initialised value. This says to me that the code typed in by the client user either hasn't been recieved by the server or didn't send from the client.
Here's the client (taken from example in docs)

#THE CLIENT use strict; use IO::Socket; my ($host, $port, $kidpid, $handle, $line); $handle = IO::Socket::INET->new( PeerAddr => "localhost", Proto => 'tcp', PeerPort => "6941") or die "can't connect to port 6941 on host localhost: $!"; print STDERR "[Connected to host:6941]\n"; $handle->autoflush(1); die "can't fork: $!" unless defined($kidpid = fork()); if ($kidpid) { while (defined ($line = <$handle>)) { print STDOUT $line; } kill("TERM", $kidpid); } else { while (defined ($line = <STDIN>)) { print $handle $line; } }

This is where I'm still a bit iffy. I'm not to sure about fork and the whole $kidpid idea. But I'm still reading so I'll eventually get it.

To sum up the main problem is that the server and client aren't communicating properly. And any help on this problem would be greatly appritiated.
Also if anybody has suggestions on how to achieve what I'm trying to do properly I'd greatly appriciate it.   


Nollaig Shona, Eoin...

Nollaig shona duit.

Replies are listed 'Best First'.
Re: Un-initalised values in Server\Client
by pg (Canon) on Dec 28, 2003 at 01:04 UTC

    So you are trying to create your own protocol. First of all, you have to clearly define your request and response before you start coding, especially the boundary of each request and response.

    The complexity you introduced by using fork() is not neccessary at all. I know why you used fork(), because your protocol is not well defined, and made you unsure about the ending of the request or response. If the protocol is clearly defined, you should be able to handle this within one process.

    Client - no more fork():

    $| ++; use IO::Socket; use strict; use warnings; my $handle = IO::Socket::INET->new( PeerAddr => "localhost", Proto => 'tcp', PeerPort => "6941") or die "can't connect to port 6941 on host localhost: $!"; print "[Connected to host:6941]\n"; my $line = <$handle>; print $line; $line = <STDIN>; print $handle $line; $line = <$handle>; print $line;

    Server - small change, and only for the communication part.

    #!/usr/bin/perl -w use strict; use IO::Socket; my $port = 6941; my $auth = " " ; my $code = " " ; #PREVENT ZOMBIES $SIG{CHLD} = 'IGNORE'; #CREATE SOCKET my $listen_socket = IO::Socket::INET->new(LocalPort => $port, Listen => 10, + Proto => 'tcp', Reuse => 1); die unless $listen_socket; warn "Server ready. Waiting for connections ... \n"; #GET CONNECTIONS my $socket = $listen_socket->accept; #REQUEST AUTHORISATION print $socket "auth code:\n"; $code = <$socket>; #GET CODE print "$code\n"; verify($code,$socket); #SEND FOR VERIFICATION exit; #SHOULD NEVER GET HERE #VERIFY AUTHORISATION CODE sub verify{ my ($code,$socket) = @_; my $auth_code = "6941"; if($code eq $auth_code) { $auth = "1"; print $socket "Accepted\n\n"; load_interface($socket); } else { $auth = "0"; print $socket "Good bye\n\n"; exit; } } sub load_interface{ my $socket = $_[0]; exit unless( $auth == "1"); open(CONFIG,"conifg") || die "Can't load config file\n"; #THIS WILL B +E A LIST OF COMMANDS my $data = " "; while(<CONFIG>) { $data = $data . $_; } print $socket $data; print $socket "\n\nWhat would you like to do (0\1\2\3\....): "; my $cmd = <$socket>; #GET COMMAND cmd($cmd,$socket); } #THIS WILL DO COMMAND. ONLY FOR TEST PURPOSES AT THE MOMENT sub cmd{ my( $cmd,$socket) = @_; exit if($cmd == "q"); print $socket "\n\nYou chose option $cmd!!!!!!\n\n"; load_interface(); }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://317250]
Approved by exussum0
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2024-04-26 07:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found