I'm trying to create a chat server using sockets in Perl. However, when I run the Server program I get the error:
"ERROR:(9)(Bad file descriptor)(6)(+The handle is invalid) at Server.pl line 21."
and when I run the client program I get the error:
"Cannot create the socket: No connection could be made because the target machine
actively refused it."
Here is the Server program:
#!usr/bin/perl
#server.pl
use IO::Socket;
$| = 1;
print "Server Program\n";
my $lp = 12000;
my $server_socket, $new_client, $addr, $port;
$server_socket = new IO::Socket::INET (
LocalHost => '127.0.0.1',
LocalPort => $lp,
Proto => 'tcp',
Reuse => 1) or die "Cannot create the socket: $!\n";
print "Server started at port $lp \n";
while (1) {
$new_client = $server_socket->accept() or die sprintf "ERROR:(%d)(%s)(%d)(+%s)", $!,$!,$^E,$^E;
$addr = $new_client->peerhost();
$port = $new_client->peerport();
print "Connected to client at $addr at port $port ";
while(<$new_client>) {
print "Following is the text entered by client: \n";
print "$_";
}
print "Client now disconnecting..\n";
close $new_client;
}
$server_socker->close();
And here is the client:
#!usr/bin/perl
#client.pl
use IO::Socket;
$| = 1;
print "Client Program\n";
my $lp = 12000;
my $client_socket = new IO::Socket::INET (
PeerHost => '127.0.0.1',
PeerPort => $lp,
Proto => 'tcp',
Reuse => 1) or die "Cannot create the socket: $!\n";
print "Server connected at port $lp \n";
print "Enter the text to sent to the server: \n";
$user_input = <>;
chomp $user_input;
print $plient_socket;
$client_socket->send($user_input);
$client_socket->close();
I am new to this and I'm not getting where I'm going wrong. Could anybody help?
You trying to accept a connection from a socket that's not listening. Add
Listen => SOMAXCONN,
And now for off-topic comments about your code:
Always use use strict; use warnings;. It will highlight some other problems with your code.
It doesn't make any sense to relative paths on the shebang line. You're missing a /.
On the style front, it's considered bad form to declare variables ahead of where they are used. The whole point of declaring variables is to limit their scope, so declaring them at the top of the program defies the purpose.
LocalHost => '127.0.0.1' (better written as LocalHost => INADDR_LOOPBACK) makes it so you can only receive connections from 127.0.0.1. That can be useful, but I don't know if you did that intentionally. The default, INADDR_ANY, allows connections from any interface.
Related
My Procedure: i am opening a file "output.txt , readin gits last line which will have the String "PASS" or "FAIL" , if PASS if found then i want to send string "OK" to server else i have to send string "ERROR"
Issue Observed: I am not able to recieve anything on Remote Server(IP 10.5.62.1) but if try using Localhost (IP 127.0.0.1) , i am able receive the string from the client. Please help to receive the string on the remote server.
I am getting the following error
:send: Cannot determine peer address at C:\client.pl line 44
IO::Socket::send('IO::Socket::INET=GLOB(0x31cc20)', 'ERROR') called at
C:\client.pl line 44
client code :
#standard includes
use strict;
use warnings;
use diagnostics;
use IO::Socket::INET;
use IO::File;
use English;
#local variables
my $Socket;
#Create Socket for a specified port number
$Socket = new IO::Socket::INET (
PeerAddr => '10.5.62.1',
PeerPort => '4754',
Proto => 'tcp',
Listen => 1,
);
die "Could not create socket: $!\n" unless $Socket;
#open the file which is required , mapping file to INPUT Macro
open INPUT, "<output.txt";
#Reading all lines from a file and storing in #lines array
my #lines = <INPUT>;
close INPUT;
#Now #lines holds all the lines, one line in each element.
print "Last line is:\n";
#checking the last line in the file as it will have the verdict "Pass" or "Fail"
print $lines[-1];
if($lines[-1]=~ 'Pass')
{
print "Setting verdict PASS and sending OK";
#Sending Ok to Server on Ping Success
# print $Socket "\r\nOK\r\n";
$Socket->send("\r\nOK\r\n");
}
else
{
print "Setting verdict FAIL and sending ERROR";
#Sending ERROR to Server on failure
# print $Socket "\r\nERROR\r\n";
$Socket->send("ERROR");
}
#Now closing the socket as my job is done
close($Socket);
Server Code:
use IO::Socket;
my $sock = new IO::Socket::INET (
LocalHost => '10.5.62.1',
LocalPort => '4754',
Proto => 'tcp',
Listen => 1,
Reuse => 1,
);
die "Could not create socket: $!\n" unless $sock;
my $new_sock = $sock->accept();
while(<$new_sock>) {
print $_;
}
close($sock);
I have been trying to find a simple client ipv6 script
that would work with Evens server script , of course I
dont know what Im doing, so all I can do is rewrite someone
else's work until I know what Im doing ...
so here is a server script that works on Microsoft widows server
use IO::Socket::IP -register;
my $sock = IO::Socket->new(
Domain => PF_INET6,
LocalHost => "::1",
Listen => 1,
) or die "Cannot create socket - $#\n";
print "Created a socket of type " . ref($sock) . "\n";
{
$in = <STDIN>;
print $in->$sock;
redo }
of course the $in->$sock is not working, cause I dont know how to send
data using just $sock ???
so I need to know how to send information properly and
what I need is A client script to connect to the above script
using the ipv6 protocol
can anyone help with this ???
I would like to be able to send information from one
perl program to another perl program using this
being able to send information back and forth would
be Ideal ...
Thanks in advance
-Mark
That's a server socket (Listen => 1), so you have to accept a connection.
use IO::Socket::IP -register;
my $listen_sock = IO::Socket::IP->new(
LocalHost => "::1", # bind()
Listen => 1, # listen()
) or die "Cannot create socket - $#\n";
print("Listening to ".$listen_sock->sockhost()." "
.$listen_sock->sockport()."\n");
while (1) {
my $sock = $listen_sock->accept()
or die $!;
print("Connection received from ".$sock->peerhost()." "
.$sock->peerport()."\n");
while (<$sock>) {
print $sock "echo: $_";
}
}
A client:
use IO::Socket::IP -register;
#ARGV == 2 or die("usage");
my ($host, $port) = #ARGV;
my $sock = IO::Socket::IP->new(
PeerHost => $host, # \ bind()
PeerPort => $port, # /
) or die "Cannot create socket - $#\n";
print $sock "Hello, world!\n";
$sock->shutdown(1); # Done writing.
print while <$sock>;
The comments indicate the underlying system call used to perform the action.
My client.pl
#!/usr/bin/perl
use IO::Socket::INET;
use strict;
my $name = '172.20.10.189'; #Server IP
my $port = '7890';
my $socket = IO::Socket::INET->new('PeerAddr' => $name,
'PeerPort' => $port,
'Proto' => 'tcp') or die "Can't create socket ($!)\n";
print "Client sending\n";
while (1) {
my $msg = <STDIN>;
print $socket $msg;
print scalar <$socket>;
}
close $socket
or die "Can't close socket ($!)\n";
My server.pl
#!/usr/bin/perl
use IO::Socket::INET;
use strict;
my $port = "7890";
my $socket = IO::Socket::INET->new('LocalPort' => $port,
'Proto' => 'tcp',
'Listen' => SOMAXCONN)
or die "Can't create socket ($!)\n";
while (my $client = $socket->accept) {
my $name = gethostbyaddr($client->peeraddr, AF_INET);
my $port = $client->peerport;
while (<$client>) {
print "[$name $port] $_";
my #out = `$_`;
print #out;
print $client "$.: #out";
}
close $client
or die "Can't close ($!)\n";
}
die "Can't accept socket ($!)\n";
My client is sending a command (ls -lrt /) to the server and Server is supposed to run that command and send output to the client back.
Problem:-
The command is executed successfully on the server but it sends only first line to the client. If I press any key from client again the next line of output is sent to the client.
Or tell me how to send multiple line output to back to client.
Any help would be appreciated.
Thanks
Abhishek
The Server sends all lines to the client, the client however chooses to read only one line:
print scalar <$socket>;
If you remove the scalar, it should work. However, your architecture is still a security nightmare.
All servers should run in taint mode (-T switch).
Never blindly execute commands that a clients sends you. Only execute commands that pass a very strict validation test, do not run commands that just don't look malicious.
Perhaps you are trying to duplicate SSH, you might want to look at that program instead.
Your server doesn't do any kind of authentication. At least it logs all inputs.
It was a silly mistake... and I have fixed the first issue as follows and got multi-line output on the client side...
Client.pl
#!/usr/bin/perl
use IO::Socket::INET;
use strict;
my $name = '172.20.10.189'; #Server IP
my $port = '7890';
my $socket = IO::Socket::INET->new('PeerAddr' => $name,
'PeerPort' => $port,
'Proto' => 'tcp')
or die "Can't create socket ($!)\n";
print "Client sending\n";
while (1) {
my $msg = <STDIN>;
print $socket $msg;
while (<$socket>)
{
print "\n$_";
}
}
close $socket
or die "Can't close socket ($!)\n";
BUT there is one more issue -
I want my client to keep sending few other commands one after another until I close the client manually and receive output.
The problem is - It receives output of the first command only..
Can anyone now help me on this?
--|proxy|--|mux|--|demux|--|proxy|--
--
--
--
machineA satellite link machineB
172.16.1.224 172.16.1.218
Greetings,
I have setup as above. I'm trying to create 'mux'. Basically, it reads traffic from a proxy and splits it up for transmission over 4 wires. The 'demux' reads off 4 wires and forwards traffic on to the proxy.
I've got a basic client/server setup in Perl. But I don't know how to get traffic from the proxy into 'mux'?
Here is my code:
server.pl -- runs on 172.16.1.218
use IO::Socket;
$| = 1;
$socket = new IO::Socket::INET (
LocalHost => '172.16.1.218',
LocalPort => '5000',
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "Coudn't open socket" unless $socket;
print "\nTCPServer Waiting for client on port 5000";
while(1)
{
$client_socket = "";
$client_socket = $socket->accept();
$peer_address = $client_socket->peerhost();
$peer_port = $client_socket->peerport();
#print "\n I got a connection from ( $peer_address , $peer_port ) ";
while (1){
$send_data = <STDIN>;
$client_socket->send($send_data);
$client_socket->recv($recieved_data,10);
print $recieved_data;#."\n";
#$client_socket->autoflush();
}
}
and:
client.pl
use IO::Socket;
$socket = new IO::Socket::INET (
PeerAddr => '172.16.1.224',
PeerPort => 5000,
Proto => 'tcp',
)
or die "Couldn't connect to Server\n";
while (1) {
$socket->recv($recv_data,10);
print $recv_data."\n";
$send_data = <STDIN>;
$socket->send($send_data);
}
I'm just a bit stuck and would appreciate any comments.
Many thanks in advance,
Your server is handling just one connection. You should use an array of connections (#socket).
You have two infinite loops nested. Since the inner one is never going to finish, you are going to attend only the first connection.
This seems a typical chat server, so i recommend you to search Google for "perl chat server". Here you have some source code that can be of help:
http://sourceforge.net/projects/perlchat/
I am trying to write a simple IO::Socket connection in perl. However, I am running into some problems. Here is the code on the server side:
my $listener =
IO::Socket::INET->new( LocalPort => 8000, Listen => 1, Reuse => 1 );
die "Can't create socket for listening: $!" unless $listener;
print "Listening for connections on port 8000\n";
while(1) {
while ($client = $listener->accept()) {
while ( <$client>) {
my #arguments = split(/ /, $_ );
my $result = "something" ;# here we do something in my code
warn $result;
print $client $result;
close $client;
}
}
}
And the client code:
use IO::Socket;
my $sock = new IO::Socket::INET (
PeerAddr => 'xx.xxx.xxx.xxx',
PeerPort => '8000',
Proto => 'tcp',
);
die "Could not create socket: $!\n" unless $sock;
$sock->autoflush(1);
print $sock "somethin something";
print "sent\n";
while ( <$sock> ) { print }
close $sock;
My problem now is that the data seems to be only sent from the client to teh sever when I close the client Perl program. I get the "sent" message on the client side, but the "something" message on the server side does not appear until after I have manually closed the client side.
Also, I want to get the server response. Thus far, since I have to close the script manually, the response does not et to the client side.
Can anyone help?
while ( <$sock> ) -- waits for a line. That is for a string, ended by "\n" character.
You must add "\n" to strings, or use 'read' function instead.