Client/Server Help!


B

bob Smith

I am trying to setup a client that sends info to a server and then the
server responsds back to the client with a response from the info it sent
across the open socket. I am new and I know I missing something. I have
looked at several examples and have taken from them all but can't get all to
work together.

1. I've gotten the client to send to the server and the server recieves
2. I've gotten the client to connect and the server to send to it.

I can't get those 2 things to happen within the same program. I know that I
need to probably say from the client "Hey I am done sending and I am ready
to recieve" but I haven't figured out how to do it. Here is my code below.
Any help would be appreciated even if you can point me to a simple example.

Client code:

#!/usr/bin/perl -w
use IO::Socket;
$sock = new IO::Socket::INET (PeerAddr => 'localhost',
PeerPort => 5150,
Proto => 'tcp'
);
die "Socket could not be created. Reason: $!\n" unless $sock;
foreach (1 .. 10) {
print "Hello $_: \n";
print $sock "Msg $_: How are you?\n";
#$sock->flush();
}
print "quit";
print $sock "quit";
$sock->flush();
my $line;
while (defined($line = <$sock>)) {
print $line;
}
close ($sock);


Server code:

#!/usr/bin/perl -w
use Socket;

my $host = 'localhost';
my $port = 5150;
my $proto = getprotobyname('tcp');

my $iaddr = inet_aton($host);
my $paddr = sockaddr_in($port, $iaddr);

socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "setsock: $!";

bind(SERVER, $paddr) or die "bind: $!";
listen(SERVER, SOMAXCONN) or die "listen: $!";

my $client_addr;
while ($client_addr = accept(CLIENT, SERVER)) {

while (defined($buf = <CLIENT>)) {
print "$buf\n";
}

my ($client_port, $client_ip) = sockaddr_in($client_addr);
my $client_ipnum = inet_ntoa($client_ip);
my $client_host = gethostbyaddr($client_ip, AF_INET);

print "got a connection from: $client_host","[$client_ipnum]\n";

print CLIENT "Smile from the server\n";
close CLIENT;
}
 
Ad

Advertisements

B

Brian McCauley

bob Smith said:
I know that I need to probably say from the client "Hey I am done
sending and I am ready to recieve" but I haven't figured out how to
do it.
Client code:
print $sock "quit";
$sock->flush();

So "quit" is your protocol's "Hey I am done sending and I am ready to
recieve".
Server code:
while (defined($buf = <CLIENT>)) {
print "$buf\n";
}

Two problems there:

One: you are reading in line mode - so the client would need to send
"quit\n" not just "quit".

Two: you are not breaking out of the loop when you get the "quit".

You may also want to consider shutdown().

None of this really has to do with Perl - it's much the same in any
language using sockets.

I have a nagging doubt that there's also a problem using "\n" across
platforms.
 
A

A. Sinan Unur

I can't get those 2 things to happen within the same program. I know
that I need to probably say from the client "Hey I am done sending and
I am ready to recieve" but I haven't figured out how to do it.

perldoc -f shutdown

Here is an untested example:

---- SimpleServer.pl ----

#! C:/Perl/bin/perl.exe

use strict;
use warnings;

use IO::Socket::INET;

my $server = IO::Socket::INET->new(
'LocalAddr' => '127.0.0.1',
'LocalPort' => '50000',
'ReuseAddr' => 1,
'Blocking' => 1,
'Proto' => 'tcp',
'Listen' => 10,
);

die "Cannot create listening socket: $!\n" unless $server;

while( 1 ) {
while(my $conn = $server->accept()) {
printf("New connection from %s:%s\n",
$conn->peerhost(), $conn->peerport());
while(<$conn>) {
print "MSG: $_\n";
}
$conn->shutdown(0);
$conn->printflush('Thank you for your message');
$conn->shutdown(2);
}
}

__END__


---- SimpleClient.pl ----

#! C:/Perl/bin/perl.exe

use strict;
use warnings;

use IO::Socket::INET;

my $server = shift || '127.0.0.1';
my $port = shift || 50000;
my $msg = join("\n", @_) || 'Hi there server dude ...';

print "Connecting to $server:$port to send \"$msg\"\n";

my $conn = IO::Socket::INET->new(
'PeerAddr' => $server,
'PeerPort' => $port,
'Blocking' => 1,
'Proto' => 'tcp'
);

die "Cannot connect: $!\n" unless $conn;

$conn->printflush($msg);
$conn->shutdown(1);
while(<$conn>) {
print;
}
$conn->shutdown(2);

__END__


---- SimpleClient.pl ----

use strict;
use warnings;

use IO::Socket::INET;

my $server = '127.0.0.1';
my $port = 50000;
my $msg = 'Hello there server dude ...';

print "Connecting to $server:$port to send \"$msg\"\n";

my $conn = IO::Socket::INET->new(
'PeerAddr' => $server,
'PeerPort' => $port,
'Blocking' => 1,
'Proto' => 'tcp'
);

die "Cannot connect: $!\n" unless $conn;

$conn->printflush($msg);
$conn->shutdown(1);
while(<$conn>) {
print;
}
$conn->shutdown(2);

__END__
 
A

A. Sinan Unur

my $msg = join("\n", @_) || 'Hi there server dude ...';

Please replace this line with

my $msg = 'Hi there server dude ...';

in the example in my previous response.
 
B

bob Smith

You the man. Thank you very much. I just needed that shutdown. I was able
to incorparate that in to my programs and it worked. That was greatly
appreciated.
 
Ad

Advertisements

A

Alan J. Flavell

I have a nagging doubt that there's also a problem using "\n" across
platforms.

perldoc perlport encourages the use of CRLF (\015\012) when doing
sockets, for its benefits in terms of cross-platform working. It's
also a practice that's heavily supported by the Internet RFC protocols
for interworking compatibility. I'm sure you're right to be doubtful
about a logical notation ("\n") whose physical embodiment differs
between platforms.

(but I'm sure you knew that already)
 
Ad

Advertisements


Top