shinoy.m
shinoy.m

Reputation: 151

In perl socket programming how to send a data from client and receive it from server

I am using Socket module to perform socket programming in Perl.And now I want to send one data from the client and receive it from the Server side. How I will achive this. Please help.

Given below in the code i used

server

#!/usr/bin/perl -w
# Filename : server.pl

use strict;
use IO::Socket;
use Socket;
use Sys::Hostname;
use constant BUFSIZE => 1024;

# use port 7890 as default
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost";  # Host IP running the server

# create a socket, make it reusable
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
   or die "Can't open socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
   or die "Can't set socket option to SO_REUSEADDR $!\n";

# bind to a port, then listen
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "Can't bind to port $port! \n";

listen(SOCKET, 5) or die "listen: $!";
print "SERVER started on port $port\n";

# accepting a connection
my $client_addr;
my $val = 100;

while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
   # send them a message, close connection
   my $name = gethostbyaddr($client_addr, AF_INET );
   print NEW_SOCKET "Smile from the server";
   print NEW_SOCKET $val;
   print "Connection recieved from $name\n";
   close NEW_SOCKET;
}

client

#!/usr/bin/perl -w
# Filename : client.pl

use strict;
use IO::Socket;
use Socket;
use Sys::Hostname;
use constant BUFSIZE => 1024;

# initialize host and port
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost";  # Host IP running the server

# create the socket, connect to the port
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
   or die "Can't create a socket $!\n";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "Can't connect to port $port! \n";

my $line;
my $req = 1000;
while ($line = <SOCKET>) {
        print "$line\n";
}
close SOCKET or die "close: $!";

Upvotes: 3

Views: 6913

Answers (1)

zdim
zdim

Reputation: 66873

Here is a basic example. The code below adds to what you have, but please note that modules IO::Socket::IP or core IO::Socket::INET make it easier than the lower level calls you use.

The only changes to your code (other than shown below) are from SOCKET to lexical my $socket, and an existing declaration is moved inside the while condition.

Every server-client system needs a protocol, an arrangement of how the messages are exchanged. Here, once the client connects the server sends a message and then they exchange single prints.

server.pl

# ... code from the question, with $socket instead of SOCKET

use IO::Handle;  # for autoflush

while (my $client_addr = accept(my $new_socket, $socket)) 
{
   $new_socket->autoflush;
   my $name = gethostbyaddr($client_addr, AF_INET );
   print "Connection received from $name\n";

   print $new_socket "Hello from the server\n";

   while (my $recd = <$new_socket>) {
       chomp $recd;
       print "Got from client: $recd\n";

       print $new_socket "Response from server to |$recd|\n";
   }   
   close $new_socket;
}

Instead of loading IO::Handle you can make a handle hot (autoflush) using select.

client.pl

I add a counter $cnt to simulate some processing that leads to a condition to break out.

# ... same as in question, except for $socket instead of SOCKET

use IO::Handle;
$socket->autoflush;

my $cnt = 0;
while (my $line = <$socket>) {
    chomp $line;
    print "Got from server: $line\n";
    last if ++$cnt > 3;                # made up condition to quit

    print $socket "Hello from client ($cnt)\n";
}
close $socket or die "close: $!";

This behaves as expected. The client exits after three messages, the server stays waiting. If you wish to indeed write just once the simple print and read replace the while loops.

The exchanges can be far more sophisticated, see the example in perlipc linked at the end.

A few comments

  • Using the mentioned modules makes this much easier

  • Any glitch in flushing can lead to deadlocks, where one party wrote and is waiting to read, while the other did not get the message still sitting in the pipe and is thus, also, waiting to read

  • Check everything. All checking is left out for brevity

  • use warnings; is better than the -w switch. See the discussion on warnings page

This is only meant to answer the question of how to enable communication between them. One good resource for study is perlipc, which also has a full example. The docs for involved modules provide a lot of information as well.

Upvotes: 2

Related Questions