I'm running this script in perl and correctly putting in the id and port. however, I keep getting "scalar found where operator expected at line 16 near"'skype://1024,'$ARGV"
#!usr/perl/bin
use LWP::UserAgent;
system("color a");
system("title Skype <<");
system("cls");
if(!$ARGV[0]||!$ARGV[1]) {
print q {
Usage : perl skype.pl [userid] [port=1024,80,433]
};
}
else {
use IO::Socket;
my $sock = new IO::Socket::INET (
PeerAddr => 'skype://'.$ARGV[0],
PeerPort => 'skype://1024,'$ARGV[1],
Proto => 'tcp',
);
die "Video Call Error: $!\n" unless $sock;
print $sock "skype://0x77656263616d5f647269766572\n";
system("start ".$sock);
}
# jvoid(document.write(document.currentUser.id));
You have a typo there:
PeerPort => 'skype://1024,'$ARGV[1],
Should be:
PeerPort => 'skype://1024,'.$ARGV[1],
# ^--- missing period
Related
Hello everyone i am new to perl scripting and below is my perl script
#!/usr/bin/perl
#use strict;
use warnings;
use 5.010;
I am getting the error
Can't use an undefined value as a symbol reference at ./sendEvent.pl line 66.
can anyone please tell me what is the issue?
It seems as though your socket isn't connected, as that's where the undefined reference is being generated.
Try ensuring that your socket is opened with the IO::Socket call...
$sock = IO::Socket::INET->new(PeerAddr => "$hostname",
PeerPort => "$port",
Proto => 'tcp')
or die "can't connect to port $port on $hostname: $!";
or somesuch.
See where that gets you. At the very least you'll know whether the socket connects correctly.
Attn: OP
Suggestion: use of hash simplifies typing and make code more readable
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use IO::Socket;
use Getopt::Long qw(GetOptions);
use Data::Dumper;
my %unit;
my #keys = qw(host port source name value part ptype module);
my #threshold = ("1000000");
# Defaults to avoid typing parameters
%unit = (
host => 'igloz118',
port => '2010',
source => 'APG_HEALTH',
name => 'RawValueCount',
value => '1000002',
part => 'APG',
ptype => 'APG-Frontend',
module => 'connecting',
devtype => 'Host',
group => 'group',
dname => '.lss.emc.com'
);
GetOptions(
'host|h=s' => \$unit{host},
'port|p=s' => \$unit{port},
'source|s=s' => \$unit{source},
'name|n=s' => \$unit{name},
'value|v=s' => \$unit{value},
'part|p=s' => \$unit{part},
'ptype|pt=s' => \$unit{ptype},
'module|m=s' => \$unit{module}
) or die "Usage: $0 --n NAME\n";
$unit{device} = $unit{host}.$unit{dname};
say '::: Parameters :::::';
printf "%-8s = %s\n", $_, $unit{$_} for #keys;
say '::::::::::::::::::::';
my $sock = IO::Socket::INET->new(
PeerAddr => $unit{hostname},
PeerPort => $unit{port},
Proto => 'tcp'
) or die "can't connect to port $unit{port} on $unit{host}: $!";;
#keys = qw/group variable value device devtype module part parttype name threshold source/;
for (my $i = 0; $i <=0 ; $i++) {
my($timestamp,$raw);
$timestamp = time;
$unit{threshold} = $threshold[$i];
$unit{variable} = join '.', #unit{qw/source device part name/};
$raw = join "\t", ( '+r', $timestamp, #unit{#keys} );
print "$raw";
print $sock "$raw";
}
close($sock);
I have the following code:
use IO::Socket::INET;
use Sys::Hostname;
use Socket;
my($addr)=inet_ntoa((gethostbyname(hostname))[4]);
my $port_to_use = 7777;
my $socket = new IO::Socket::INET (
LocalHost => $addr,
LocalPort => $port_to_use,
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "cannot create socket $!\n" unless $socket;
my $client_socket = $socket->accept();
if i start this in one screen and start another one in the other screen, i get an error:
cannot create socket Address already in use
instead of dying, i would like to try using different port (increment by 1) until it can find the one to use.
I've try to convert the die line with eval but im not able to catch it
any suggestions?
Use a Loop:
use IO::Socket::INET;
use Sys::Hostname;
use Socket;
my($addr)=inet_ntoa((gethostbyname(hostname))[4]);
my $port_to_use = 7776;
my $fail =1;
my $socket;
while ($fail == 1){
$port_to_use++;
$fail = 0;
warn $port_to_use;
$socket = IO::Socket::INET->new (
LocalHost => $addr,
LocalPort => $port_to_use,
Proto => 'tcp',
Listen => 5,
Reuse => 0
) or $fail =1;
}
warn $socket->accept();
Here is a tidier alternative which actually checks to make sure the failure to bind to a given port was due to the port being in use. It also limits the port range to check. If you use the code in the other answer, and, if for some reason, the machine is not allowing your application to bind to any ports, you are going to get stuck in an infinite loop. It may also cause your application to bind to ports that should otherwise have been left alone etc.
#!/usr/bin/env perl
use strict;
use warnings;
use Carp qw( croak );
use Errno qw( EADDRINUSE );
use IO::Socket::INET;
use Sys::Hostname qw( hostname );
use Socket;
# These can come from a config file or command line
# See also https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic.2C_private_or_ephemeral_ports
# https://unix.stackexchange.com/a/39784/2371
my #port_range = (0xC000, 0xFFFF);
my $addr = inet_ntoa( (gethostbyname(hostname) )[4]);
my $socket;
TRY_PORT:
for my $port ($port_range[0] .. $port_range[1]) {
warn "Trying port $port\n";
$socket = IO::Socket::INET->new(
LocalHost => $addr,
LocalPort => $port,
Proto => 'tcp',
Listen => 7,
Reuse => 0,
);
if ($socket) {
warn "Bound to port $port\n";
last TRY_PORT;
}
if ( EADDRINUSE != $! ) {
croak "Cannot bind to port '$port': $!";
}
warn "Port in use, trying the next one\n";
}
$socket->accept
or croak "...";
# ...
This is my current code:
#!/usr/bin/perl -w
use strict;
require IO::Socket;
while (<>) {
chomp(my $host = $_);
my #header;
print "Connecting to: $host\n";
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp') || print "Could not connect: $!\n";
print "Connected.\n";
print $socket "GET / HTTP/1.0\n\n";
my $i = 0;
while (<$socket>) {
#header[$i] = $_;
$i++;
}
$i = 0;
print "--------------------------------------\n";
while ($i <= 8) {
print "#header[$i++]";
}
print "-------------------------------------\n";
print "Finished $host\n\n";
}
If while going through a list of IP's, and a host is down, instead of continuing onto the next IP, it will give me an error "Can't use string ("1") as a symbol ref while "strict refs" in use".
If I then change #header[$i] = $; to $header[$i] = $; I also get the same error. How can I make this script better.
The problem is in the way you set $socket:
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp') || print "Could not connect: $!\n";
Since you're using the || operator, which has higher precedence than =, this statement is parsed as
my $socket = (new IO::Socket::INET(...) || print ...);
If new IO::Socket::INET returns a false value (as it does if the connection fails), the print will be executed and its return value (which is normally 1) will be assigned to $socket.
When you then try to use $socket as an indirect object in the statement:
print $socket "GET / HTTP/1.0\n\n";
Perl notices that the value 1 is not actually an object reference and throws the error you reported.
If you'd used the low-precedence operator or instead of ||, the value of $socket would've been undef instead of 1, and the error message you'd have received would've been something like Can't use an undefined value as a symbol reference .... Of course, this wouldn't have actually fixed your problem, but at least it might've made it easier to diagnose.
To actually fix the problem, you need to fix your code so that you won't keep executing the rest of the loop body if the connection fails. One way to do that would be like this:
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp');
unless ($socket) {
print "Could not connect: $!\n";
next; # skip the rest of the loop
}
Wouldn't the simple solution be to use the lower precedence version 'or' which has lower precedence than '='?
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp')
or print "Could not connect: $!\n";
In fact, the operators 'or', and 'xor', have the lowest operator precedence (see perlop).
I've been trying to debug this perl issue for awhile but had made no head way. what I'm trying to do is determain if the connection is a socks4/5 connection.
# ./pctest.pl
Name "main::junk" used only once: possible typo at ./pctest.pl line 60.
Name "main::empty" used only once: possible typo at ./pctest.pl line 60.
IO::Socket::INET: Bad hostname 'C1(X' ...propagated at ./pctest.pl line 52.
I've also had this error (before i added or die #$; at the end):
Can't use an undefined value as a symbol reference at ./pctest.pl line 56.
.
...
$look = IO::Socket::INET->new( PeerAddr => $_, Proto => 'tcp', Timeout => 5 ) or die #$;
$sock4 = pack( "CCS", 4, 1, 80 );
print $look $sock4;
read( $look, $recv, 10 );
( $empty, $granted, $junk ) = unpack( "C C C6", $recv );
if( $granted == 0x5A )
{
print " Yes\n";
}
else
{
print " No\n";
}
...
There's a typo. #$ should really be $#.
To get rid of the "possible typo" messages and since $empty and $junk seem to be unused in your code, write:
my #result = unpack("C C C6", $recv);
if ($result[1] == 0x5A) {
# ...
}
Just a side note : I think you are thinking of $#, instead of #$. You need to enclose the code in an
eval { ... };
construction. See:
my $look;
eval { $look = IO::Socket::INET->new( PeerAddr => $_, Proto => 'tcp', Timeout => 5 ) };
if ($#) {
do_something_with($#);
}
Granted, that doesn't answer the original question :)
The error message means that your parameter value for PeerAddr in the IO::Socket::INET->new call is invalid.
The constructor expects the PeerAddr value to be a hostname or an IP address (nnn.nnn.nnn.nnn). Check the contents of $_ and I bet you'll find something different.
I'm trying to connect to some host, using invalid port, and i want to get timeout after X seconds. How to do that ?
My code:
$sock = new IO::Socket::INET(
PeerAddr => $_[0],
PeerPort => $_[1],
Proto => 'tcp',
Timeout => 2
);
If you check the code you'll see (I copied it from my Ubuntu 10.04) :
my $timeout = ${*$sock}{'io_socket_timeout'};
# my $before = time() if $timeout;
undef $#;
if ($sock->connect(pack_sockaddr_in($rport, $raddr))) {
# ${*$sock}{'io_socket_timeout'} = $timeout;
return $sock;
}
return _error($sock, $!, $# || "Timeout")
unless #raddr;
# if ($timeout) {
# my $new_timeout = $timeout - (time() - $before);
# return _error($sock,
# (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() : $EINVAL),
# "Timeout") if $new_timeout <= 0;
# ${*$sock}{'io_socket_timeout'} = $new_timeout;
# }
Apparently the timeout stuff is commented out so that expleins why it is ignored.
I found a post dating from 2003 where this was discussed. One suggestion (at the bottom) was to open the socket in an eval block which gets terminated by an alarm signal :
eval {
local $SIG{ALRM} = sub { die 'Timed Out'; };
alarm 3;
my $sock = IO::Socket::INET->new(
PeerAddr => inet_ntoa( gethostbyname($host) ),
PeerPort => 'whois',
Proto => 'tcp',
## timeout => ,
);
$sock->autoflush;
print $sock "$qry\015\012";
undef $/; $data = <$sock>; $/ = "\n";
alarm 0;
};
alarm 0; # race condition protection
return "Error: timeout." if ( $# && $# =~ /Timed Out/ );
return "Error: Eval corrupted: $#" if $#;
Not very elegant, but if it works...
Let's verify with a slow server and impatient client :
# Impatient Client
use IO::Socket::INET;
$sock = new IO::Socket::INET(
PeerAddr => "localhost",
PeerPort => "10007",
Proto => 'tcp',
Timeout => 2,
);
print <$sock>;
close($sock);
# SlowServer
use IO::Socket::INET;
$sock = new IO::Socket::INET(
LocalAddr => "localhost",
LocalPort => "10007",
Proto => 'tcp',
Listen => 1,
Reuse => 1,
);
$newsock = $sock->accept();
sleep 5;
#while (<$newsock>) {
# print $_;
#}
print $newsock "Some Stuff";
close($newsock);
close($sock);
if we run this:
pti#pti-laptop:~/playpen$ perl server.pl&
[1] 9130
pti#pti-laptop:~/playpen$ time perl test.pl
Some Stuff[1]+ Done perl server.pl
real 0m5.039s
user 0m0.050s
sys 0m0.030s
So it ignores the 2 second timeout and runs for the full 5 seconds.
Now the other impatient client :
use IO::Socket::INET;
eval {
local $SIG{ALRM} = sub { die 'Timed Out'; };
alarm 2;
$sock = new IO::Socket::INET(
PeerAddr => "localhost",
PeerPort => "10007",
Proto => 'tcp',
Timeout => 2,
);
print <$sock>;
close($sock);
alarm 0;
};
alarm 0; # race condition protection
print "Error: timeout." if ( $# && $# =~ /Timed Out/ );
print "Error: Eval corrupted: $#" if $#;
~
and running it :
pti#pti-laptop:~/playpen$ perl server.pl&
[1] 9175
pti#pti-laptop:~/playpen$ time perl test2.pl
Error: timeout.Error: Eval corrupted: Timed Out at test2.pl line 3.
real 0m2.040s
user 0m0.020s
sys 0m0.010s
Yep, this timeouts after 2 seconds as expected.
So much easier is to use the
IO::Socket::Timeout
as per below and it works like a charm.
use IO::Socket::Timeout;
my $socket = IO::Socket::INET->new( Timeout => 2 );
IO::Socket::Timeout->enable_timeouts_on($socket);
$socket->read_timeout(0.5); # These will work
$socket->write_timeout(0.5); # These will work