Schrift
[thread]4304[/thread]

IO::Socket Problem: Socket braucht zu lange

Leser: 2


<< >> 8 Einträge, 1 Seite
coax
 2005-05-25 18:48
#37698 #37698
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
Erst einmal use warnings; und use strict;, damit wirst du eine Menge Probleme loesen und weiteren Problemen vorbeugen.
Code: (dl )
1
2
3
4
my @OPorts;
my $a = -1;
# [ ... ]
@OPorts[$a] = $i; $a++;

Das tut so nicht funktionieren, weil du spaeter erst der Arrayvariable mit dem Index -1 ($OPorts[-1]) etwas zuweist und erst danach $a inkrementierst - das ist illegal ;).

Code: (dl )
@OPorts[$a] = $i; $a++;

@OPorts[$a] ist ein Array-Slice, du willst sicher $OPorts[$a] (mit use warnings haettest du auch eine entsprechende Warnung bekommen Scalar value @OPorts[$a] better written as $OPorts[$a]).

Statt globaler Variablen ($startport, $stopport, $host) kannst du mit Parameteruebergabe arbeiten
Code: (dl )
&scanstart($host, $startport, $stopport);

Code: (dl )
1
2
3
sub scanstart {
   my($host, $startport, $stopport) = @_;
# [ ... ]

Auch die Pruefung
Code: (dl )
1
2
3
4
5
6
if (&socket($host, $i) eq "True") {
   print "\t* Port $i; Open!\n";
   $OPorts[$a] = $i;
   $a++;
}
else { print "\t* Port $i; Closed!\n" }

kannst du dir etwas vereinfach;
Der IO::Socket-Konstruktur liefer naemlich undef zurueck falls ein Fehler aufgetreten ist (Fehlermeldung steckt in $@),
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
sub socket {
  my($host, $cport) = @_;

  my $socket = IO::Socket::INET->new (
   PeerAddr => $host,
   PeerPort => $cport,
   Proto => "tcp",
   Timeout => 1,
   Type => SOCK_STREAM
  );
  return $socket;
}
Wenn du dein True, False beibehalten willst
Code: (dl )
return $socket ? "True" : "False";

Code: (dl )
1
2
3
4
5
if ( &socket($host, $i) ) {
   print "\t* Port $i; Open!\n";
   $OPorts[$a] = $i;
   $a++;
   } else { print "\t* Port $i; Closed!\n" }

Das hier fuehrt zwar zu den erwuenschte Ergebnis
Code: (dl )
) || { $bool = "False" };

ist aber ein ueberfluessiges Konstrukt, die geschweiften Klammern stellen naemlich ein anonymer Hash dar und kein Anweisungsblock ($bool = "False" wird trotzdem ausgewertet). So waer's richtig...
Code: (dl )
1
2
3
4
5
6
) || ( $bool = "False" )
# oder so etwas...
my $socket = IO::Socket::INET->new (
# [ ... ]
);
my $bool = $socket ? "True" : "False";

edit:
Code: (dl )
foreach $pp (@OPorts) { print "$pp, " }
kuerzer
Code: (dl )
print join ',' => @OPorts
jetzt ist da auch kein stoerendes Komma mehr hinter'm letzten Wert.

Die Variable $a kannst du dir sparen, wobei der Bezeichner auch noch schlecht gewaehlt ist
Code: (dl )
1
2
3
4
5
6
7
8
foreach my $port ( $startport .. $stopport ) {
   if # [ ... ] port offen
       # [ ... ]
       push @OPorts, $port;
   else { # port geschlossen
       # [ ... ]
   }
}


Grusz Christian.\n\n

<!--EDIT|coax|1117037897-->
,,Das perlt aber heute wieder...'' -- Dittsche
esskar
 2005-05-26 07:00
#37699 #37699
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
das selbe problem hatte ich heute auch schon;
man kann den timeout des socket connects (wird von new aufgerufen) nicht wirklich beinflussen...
da musst du schon asyncchron ran gehen...
Strat
 2005-05-26 20:50
#37700 #37700
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
vielleicht mal auf http://poe.perl.org/?POE_Cookbook schauen? POE muesste fuer sowas recht gut funktionieren
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
esskar
 2005-05-30 17:14
#37701 #37701
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
ungetestet:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use strict;
use warnings;

use IO::Socket::INET;

my $sock = IO::Socket::INET->async_new(
PeerAddr => 'board.perl-community.de',
PeerPort => 80,
Proto => "tcp",
Timeout => 1,
Type => SOCK_STREAM,
AsyncTimeout => 1000
);


package IO::Socket;

use strict;
use warnings;

use threads;
use threads::shared;

my $can_connect = 0;
my $is_shared = 0;

sub async_new_cb {
  my ($self, $sockref, %args) = @_;

  ${$sockref} = $self->new(%args);
  $can_connect = 1;
  cond_signal($can_connect);
}

sub async_new {
  my ($self, %args) = @_;

  $args{AsyncTimeout} ||= 1000;  
 
  my $sockobj = undef;
  my $thread = threads->create('async_new_cb', $self, \$sockobj, %args);
 
  unless($is_shared) {
  share($can_connect);
  $is_shared = 1;
  }

  $can_connect = 0;
  lock($can_connect);
     
  until($can_connect) {  
  last if !cond_timedwait($can_connect, time() + $args{AsyncTimeout});
  }

  return $can_connect ? $sockobj : undef;
}

1;
GloBoX
 2005-05-25 14:24
#37702 #37702
User since
2005-05-25
8 Artikel
BenutzerIn
[default_avatar]
Hi,

Der Portscanner funktioniert allderdings braucht der Socket fast über eine Minute braucht ein Port zu scannen obwohl ich timeout auf 1 gesetzt habe. Wenn ich localhost scanne gehts auch schnell im Internet allerdings nicht. Weiß jemand wie man das schneller machen könnte?

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#Portscanner

use IO::Socket;

$info = "\t* Simple Portscanner by GloBoX\n\n";

sub start {
if ($#ARGV != 2) { die "Use: $0 host startport stopport\n" }
else {
$host = $ARGV[0];
$startport = $ARGV[1];
$stopport = $ARGV[2];
if ($startport >= $stopport) { die "Use: $0 host startport stopport\n" }

print $info;
&scanstart();
}
}

sub socket {
$cport = $_[0];
$bool = "True";

$socket = IO::Socket::INET->new (
PeerAddr => $host,
PeerPort => $cport,
Proto => "tcp",
Timeout => 1,
Type => SOCK_STREAM
) || { $bool = "False" };

return($bool);
}

sub scanstart {
my $a = -1;
print "\t** Scanning **\n";
for ($i = $startport; $i <= $stopport; $i++) {
if (&socket($i) eq "True") {
print "\t* Port $i; Open!\n";
@OPorts[$a] = $i; $a++;
}
else { print "\t* Port $i; Closed!\n" }
}
print "\n** Open Ports: ";
foreach $pp (@OPorts) { print "$pp, " }

}

&start();
GloBoX
 2005-05-25 21:37
#37703 #37703
User since
2005-05-25
8 Artikel
BenutzerIn
[default_avatar]
Hi Christian,

Erstmal danke für die ganzen Tips doch leider hat das nichts mit mein socket zu tun :/ bzw. löst es nicht mein Problem.

globox
coax
 2005-05-26 12:45
#37704 #37704
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
[quote=esskar,26.05.2005, 05:00]da musst du schon asyncchron ran gehen...[/quote]
..., d.h. Forking bzw. Threading ist dein Freund.\n\n

<!--EDIT|coax|1117097391-->
,,Das perlt aber heute wieder...'' -- Dittsche
supersucker
 2005-05-30 16:40
#37705 #37705
User since
2005-03-17
118 Artikel
BenutzerIn
[default_avatar]
Quote
..., d.h. Forking bzw. Threading ist dein Freund.


was würdet ihr denn empfehlen?
forken würde ja heissen für jeden port einen separaten neuen prozeß zu starten oder? das würde also bei beispielsweise 1000 zu scannenden ports 1000 neue prozeße bedeuten.....das wäre doch vermutlich sehr ineffizient oder?
also bei sowas besser zu threads greifen?
<< >> 8 Einträge, 1 Seite



View all threads created 2005-05-25 18:48.