www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Checking if a port is listening

reply Lucien <lucien.perregaux gmail.com> writes:
Hello,

I want to know if a port of an ip address is listening, actually, 
I've this :
http://pastebin.com/pZhm0ujy
(checking port 22/ssh)

It works, but it took me ~10min to scan 30 addresses.

How can reduce the expiration delay ?
Mar 16 2016
next sibling parent reply Anonymouse <asdf asdf.com> writes:
On Wednesday, 16 March 2016 at 20:44:12 UTC, Lucien wrote:
 Hello,

 I want to know if a port of an ip address is listening, 
 actually, I've this :
 http://pastebin.com/pZhm0ujy
 (checking port 22/ssh)

 It works, but it took me ~10min to scan 30 addresses.

 How can reduce the expiration delay ?
I don't know if they apply here, but you can lower the send and receive timeouts for the socket. I'm not sure which (or if either) of them you want to tweak. https://dlang.org/library/std/socket/socket_option.html import core.thread; // for .seconds s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds); s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds); I guess you could also use a non-blocking socket and decide yourself when enough time has passed to declare it a failed attempt.
Mar 16 2016
next sibling parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
 import core.thread;  // for .seconds
Nitpick: `seconds` is defined in `core.time`; `core.thread` just reexports it.
 s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
 s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);
Mar 17 2016
parent Anonymouse <asdf asdf.com> writes:
On Thursday, 17 March 2016 at 10:41:55 UTC, Marc Schütz wrote:
 On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
 import core.thread;  // for .seconds
Nitpick: `seconds` is defined in `core.time`; `core.thread` just reexports it.
 s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
 s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);
Er, yes, didn't think that through properly.
Mar 17 2016
prev sibling parent reply Lucien <lucien.perregaux gmail.com> writes:
On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
 On Wednesday, 16 March 2016 at 20:44:12 UTC, Lucien wrote:
 Hello,

 I want to know if a port of an ip address is listening, 
 actually, I've this :
 http://pastebin.com/pZhm0ujy
 (checking port 22/ssh)

 It works, but it took me ~10min to scan 30 addresses.

 How can reduce the expiration delay ?
I don't know if they apply here, but you can lower the send and receive timeouts for the socket. I'm not sure which (or if either) of them you want to tweak. https://dlang.org/library/std/socket/socket_option.html import core.thread; // for .seconds s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds); s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds); I guess you could also use a non-blocking socket and decide yourself when enough time has passed to declare it a failed attempt.
When it's non-blocking, all adresses have the open 22 open, but it isn't the case.. When I setOption like you said, it's too long. Is there a good technique ? nmap can do it in only ~2 seconds. My current code : -------------------------------------------------------- import std.process; import std.socket; import core.time; // ... // 32 for the moment for (int i = 1; i < 32; i++) { string ip = "192.168.0."~to!string(i); Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP); s.blocking = false; //s.setOption(SocketOptionLevel.SOCKET, SocketOption.SNDTIMEO, 1.seconds); //s.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, 1.seconds); InternetAddress ia = new InternetAddress(ip, 22); try { s.connect(ia); writeln("\nDONE: ", ip, ":22"); } catch (Exception e) { writeln("\n\nFAIL: ", ip, ":22 is unreachable :\n", e.toString(), "\n"); } s.close(); } // ... -------------------------------------
Mar 17 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
Looking at an strace of nmap, it seems it opens a bunch of 
sockets, puts them into non-blocking mode, calls connect on them 
(which will return EINPROGRESS), and then uses select(2) to wait 
for them (in a loop, until all have either been accepted or 
rejected). select(2) accepts a timeout value, so you can 
determine how long you want to wait.

Here's an excerpt:

...
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50
fcntl(50, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
(Operation not permitted)
setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0
connect(50, {sa_family=AF_INET, sin_port=htons(32778), 
sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation 
now in progress)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51
fcntl(51, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
(Operation not permitted)
setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0
connect(51, {sa_family=AF_INET, sin_port=htons(1029), 
sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation 
now in progress)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52
fcntl(52, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
(Operation not permitted)
setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0
connect(52, {sa_family=AF_INET, sin_port=htons(2013), 
sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation 
now in progress)
select(53, [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], [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], [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], {0, 0}) = 
100 (in [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], out [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], left {0, 0})
...

I'm pretty sure the setsockopt() calls aren't essential.
Mar 18 2016
next sibling parent Timothee Cour via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
see also:
https://github.com/rejectedsoftware/vibe.d/issues/1431 api to find an
available port




On Fri, Mar 18, 2016 at 2:50 AM, Marc Sch=C3=BCtz via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com> wrote:

 Looking at an strace of nmap, it seems it opens a bunch of sockets, puts
 them into non-blocking mode, calls connect on them (which will return
 EINPROGRESS), and then uses select(2) to wait for them (in a loop, until
 all have either been accepted or rejected). select(2) accepts a timeout
 value, so you can determine how long you want to wait.

 Here's an excerpt:

 ...
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) =3D 50
 fcntl(50, F_GETFL)                      =3D 0x2 (flags O_RDWR)
 fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   =3D 0
 setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=3D1, linger=3D0}, 8) =3D 0
 setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) =3D -1 EPERM (Operati=
on
 not permitted)
 setsockopt(50, SOL_IP, IP_TTL, [-1], 4) =3D 0
 connect(50, {sa_family=3DAF_INET, sin_port=3Dhtons(32778),
 sin_addr=3Dinet_addr("127.0.0.1")}, 16) =3D -1 EINPROGRESS (Operation now=
in
 progress)
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) =3D 51
 fcntl(51, F_GETFL)                      =3D 0x2 (flags O_RDWR)
 fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   =3D 0
 setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=3D1, linger=3D0}, 8) =3D 0
 setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) =3D -1 EPERM (Operati=
on
 not permitted)
 setsockopt(51, SOL_IP, IP_TTL, [-1], 4) =3D 0
 connect(51, {sa_family=3DAF_INET, sin_port=3Dhtons(1029),
 sin_addr=3Dinet_addr("127.0.0.1")}, 16) =3D -1 EINPROGRESS (Operation now=
in
 progress)
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) =3D 52
 fcntl(52, F_GETFL)                      =3D 0x2 (flags O_RDWR)
 fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   =3D 0
 setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=3D1, linger=3D0}, 8) =3D 0
 setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) =3D -1 EPERM (Operati=
on
 not permitted)
 setsockopt(52, SOL_IP, IP_TTL, [-1], 4) =3D 0
 connect(52, {sa_family=3DAF_INET, sin_port=3Dhtons(2013),
 sin_addr=3Dinet_addr("127.0.0.1")}, 16) =3D -1 EINPROGRESS (Operation now=
in
 progress)
 select(53, [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 5=
0
 51 52], [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 5=
1
 52], [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], {0, 0}) =3D 100 (in [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 4=
6
 47 48 49 50 51 52], out [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2=
1
 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 4=
6
 47 48 49 50 51 52], left {0, 0})
 ...

 I'm pretty sure the setsockopt() calls aren't essential.
Mar 18 2016
prev sibling parent reply Lucien <lucien.perregaux gmail.com> writes:
On Friday, 18 March 2016 at 09:50:12 UTC, Marc Schütz wrote:
 Looking at an strace of nmap, it seems it opens a bunch of 
 sockets, puts them into non-blocking mode, calls connect on 
 them (which will return EINPROGRESS), and then uses select(2) 
 to wait for them (in a loop, until all have either been 
 accepted or rejected). select(2) accepts a timeout value, so 
 you can determine how long you want to wait.

 Here's an excerpt:

 ...
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50
 fcntl(50, F_GETFL)                      = 0x2 (flags O_RDWR)
 fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
 setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 
 0
 setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
 (Operation not permitted)
 setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0
 connect(50, {sa_family=AF_INET, sin_port=htons(32778), 
 sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS 
 (Operation now in progress)
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51
 fcntl(51, F_GETFL)                      = 0x2 (flags O_RDWR)
 fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
 setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 
 0
 setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
 (Operation not permitted)
 setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0
 connect(51, {sa_family=AF_INET, sin_port=htons(1029), 
 sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS 
 (Operation now in progress)
 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52
 fcntl(52, F_GETFL)                      = 0x2 (flags O_RDWR)
 fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
 setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 
 0
 setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM 
 (Operation not permitted)
 setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0
 connect(52, {sa_family=AF_INET, sin_port=htons(2013), 
 sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS 
 (Operation now in progress)
 select(53, [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], [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], [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], {0, 0}) = 100 (in [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], out [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], left {0, 0})
 ...

 I'm pretty sure the setsockopt() calls aren't essential.
I tried: ------------------------------------------ // ... const int MAX = 64; Socket[] sockets = new Socket[MAX]; string ipb = "192.168.0."; for (int i = 1; i < MAX; i++) { string ip = ipb~to!string(i); Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP); s.blocking = false; sockets[i] = s; InternetAddress ia = new InternetAddress(ip, 22); s.connect(ia); } foreach (int i, Socket s; sockets) { SocketSet ss = new SocketSet(); //ss.add(s); if (s.select(ss, null, null, 500.msecs) > 0) { writeln("\n\nDONE: ", ipb~to!string(i), ":22"); } else { writeln("\n\nFAIL: ", ipb~to!string(i), ":22 is unreachable !\n"); } } writeln("DONE"); ------------------------------------------ When I uncomment ss.add(s); , I got the error -11. Any suggestions ?
Mar 19 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Saturday, 19 March 2016 at 09:55:13 UTC, Lucien wrote:
     const int MAX = 64;
     Socket[] sockets = new Socket[MAX];
     string ipb = "192.168.0.";

     for (int i = 1; i < MAX; i++) {
Here's the reason for your SEGV: You need to start at 0, because otherwise `sockets[0]` is `null`. When you add that to the SocketSet, it will trigger the segfault. I guess you want to skip the 0 because it represents the subnet address; in that case, you simply mustn't add `sockets[0]` to the set. But then there is another problems: You're using `select()` the wrong way. The point of using select() is that you can check things asynchronously. Your code should be structured like this (pseudo code): auto ss = new SocketSet(); for(i; 1 .. MAX) { auto s = new Socket(...); s.blocking = false; s.connect(...); ss.add(s); } while(ss.count > 0) { auto write_ss = ss.dup; auto status = Socket.select(null /* read */, write_ss /* write */, null /* error */, 500.msecs); // for a connect()ing socket, writeability means connected if(status < 0) writeln("interrupted, retrying"); else if(status == 0) writeln("timeout, retrying"); else { writeln(status, " socket(s) changed state"); for(fd; 0 .. write_ss.maxfd+1) { // check whether this socket has changed if(!write_ss.isSet(fd)) continue; // if yes, remove it from the original SocketSet ss.remove(fd); writeln("successfully connected to 192.168.0.", fd+1); } } }
Mar 19 2016
next sibling parent Lucien <lucien.perregaux gmail.com> writes:
On Saturday, 19 March 2016 at 18:24:38 UTC, Marc Schütz wrote:
 On Saturday, 19 March 2016 at 09:55:13 UTC, Lucien wrote:
     const int MAX = 64;
     Socket[] sockets = new Socket[MAX];
     string ipb = "192.168.0.";

     for (int i = 1; i < MAX; i++) {
Here's the reason for your SEGV: You need to start at 0, because otherwise `sockets[0]` is `null`. When you add that to the SocketSet, it will trigger the segfault. I guess you want to skip the 0 because it represents the subnet address; in that case, you simply mustn't add `sockets[0]` to the set. But then there is another problems: You're using `select()` the wrong way. The point of using select() is that you can check things asynchronously. Your code should be structured like this (pseudo code): auto ss = new SocketSet(); for(i; 1 .. MAX) { auto s = new Socket(...); s.blocking = false; s.connect(...); ss.add(s); } while(ss.count > 0) { auto write_ss = ss.dup; auto status = Socket.select(null /* read */, write_ss /* write */, null /* error */, 500.msecs); // for a connect()ing socket, writeability means connected if(status < 0) writeln("interrupted, retrying"); else if(status == 0) writeln("timeout, retrying"); else { writeln(status, " socket(s) changed state"); for(fd; 0 .. write_ss.maxfd+1) { // check whether this socket has changed if(!write_ss.isSet(fd)) continue; // if yes, remove it from the original SocketSet ss.remove(fd); writeln("successfully connected to 192.168.0.", fd+1); } } }
thanks, but what's the type of fd ? current code: -------------------------------- const int MAX = 64; // usefull ? Socket[] sockets = new Socket[MAX]; string ipb = "192.168.0."; SocketSet ss = new SocketSet(); for (int i = 0; i < MAX; i++) { string ip = ipb~to!string(i+1); Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP); s.blocking = false; InternetAddress ia = new InternetAddress(ip, 22); sockets[i] = s; s.connect(ia); ss.add(s); } while (ss.max > 0) { SocketSet write_ss = ss; auto status = Socket.select(null, write_ss, null, 50.msecs); // for a connect()ing socket, writeability means connected if(status < 0) writeln("interrupted, retrying"); else if(status == 0) writeln("timeout, retrying"); else { writeln(status, " socket(s) changed state"); for (int i = 0; i < write_ss.tupleof[1]; i++) { // tried to do something //Socket fd = write_ss.tupleof[0][i]; string ip = ipb~to!string(i+1); if(!write_ss.isSet(fd)) continue; ss.remove(fd); writeln("successfully connected to ", ip); } } } --------------------------------
Mar 19 2016
prev sibling parent reply Lucien <lucien.perregaux gmail.com> writes:
On Saturday, 19 March 2016 at 18:24:38 UTC, Marc Schütz wrote:
 On Saturday, 19 March 2016 at 09:55:13 UTC, Lucien wrote:
     const int MAX = 64;
     Socket[] sockets = new Socket[MAX];
     string ipb = "192.168.0.";

     for (int i = 1; i < MAX; i++) {
Here's the reason for your SEGV: You need to start at 0, because otherwise `sockets[0]` is `null`. When you add that to the SocketSet, it will trigger the segfault. I guess you want to skip the 0 because it represents the subnet address; in that case, you simply mustn't add `sockets[0]` to the set. But then there is another problems: You're using `select()` the wrong way. The point of using select() is that you can check things asynchronously. Your code should be structured like this (pseudo code): auto ss = new SocketSet(); for(i; 1 .. MAX) { auto s = new Socket(...); s.blocking = false; s.connect(...); ss.add(s); } while(ss.count > 0) { auto write_ss = ss.dup; auto status = Socket.select(null /* read */, write_ss /* write */, null /* error */, 500.msecs); // for a connect()ing socket, writeability means connected if(status < 0) writeln("interrupted, retrying"); else if(status == 0) writeln("timeout, retrying"); else { writeln(status, " socket(s) changed state"); for(fd; 0 .. write_ss.maxfd+1) { // check whether this socket has changed if(!write_ss.isSet(fd)) continue; // if yes, remove it from the original SocketSet ss.remove(fd); writeln("successfully connected to 192.168.0.", fd+1); } } }
This code works fine : ------------------------------ import std.stdio; import std.socket; import std.conv; import core.time; import core.thread; void main() { const int MAX = 254, TRIES = 5; Socket[] sockets = new Socket[MAX]; string ipb = "192.168.0."; SocketSet ss = new SocketSet(); for (int i = 0; i < MAX; i++) { string ip = ipb~to!string(i+1); Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP); s.blocking = false; InternetAddress ia = new InternetAddress(ip, 22); sockets[i] = s; s.connect(ia); ss.add(s); } Thread.sleep(100.msecs); for (int t = 0; t < TRIES; t++) { SocketSet write_ss = ss; int status = Socket.select(null, write_ss, null, 100.msecs); if(status < 0) writeln("interrupted, retrying"); else if(status == 0) { writeln("timeout, retrying"); } else { writeln(status, " socket(s) changed state"); for (int i = 0; i < write_ss.tupleof[1] -2; i++) { string ip = "192.168.0."~to!string(i+1); Socket fd = sockets[i]; if(!ss.isSet(fd)) continue; ss.remove(fd); writeln("successfully connected to ", ip); } } } writeln("DONE"); } ------------------------------ When I remove the Thread.sleep, it doesn't find all adresses. Why ?
Mar 23 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Wednesday, 23 March 2016 at 21:37:09 UTC, Lucien wrote:
 When I remove the Thread.sleep, it doesn't find all adresses. 
 Why ?
Socket.select() will wait _at most_ 100 msecs. If a socket gets ready before that timeout, it will return immediately. Therefore, you might not get the full TIMES*100 msecs, and some hosts might not have responded in time.
Mar 24 2016
parent Lucien <lucien.perregaux gmail.com> writes:
On Thursday, 24 March 2016 at 12:17:35 UTC, Marc Schütz wrote:
 On Wednesday, 23 March 2016 at 21:37:09 UTC, Lucien wrote:
 When I remove the Thread.sleep, it doesn't find all adresses. 
 Why ?
Socket.select() will wait _at most_ 100 msecs. If a socket gets ready before that timeout, it will return immediately. Therefore, you might not get the full TIMES*100 msecs, and some hosts might not have responded in time.
If I change Thread.sleep(100.msecs) to Thread.sleep(6.seconds), all hosts respond. What am I doing false ? I don't understand..
Mar 24 2016
prev sibling parent Lucien <lucien.perregaux gmail.com> writes:
On Wednesday, 16 March 2016 at 20:44:12 UTC, Lucien wrote:
 Hello,

 I want to know if a port of an ip address is listening, 
 actually, I've this :
 http://pastebin.com/pZhm0ujy
 (checking port 22/ssh)

 It works, but it took me ~10min to scan 30 addresses.

 How can reduce the expiration delay ?
Finally solved : --------------------------------------------- import std.stdio; import std.socket; import std.conv; import core.time; import core.thread; void main() { enum TRIES = 5, MAX = 254; string subnet = "192.168.0."; Socket[] sockets = new Socket[MAX]; SocketSet ss = new SocketSet(MAX + 1); for (int i = 0; i < MAX; i++) { string ip = subnet~to!string(i+1); InternetAddress ia = new InternetAddress(ip, 22); TcpSocket s = new TcpSocket(); s.blocking = false; s.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, 100.msecs); s.setOption(SocketOptionLevel.SOCKET, SocketOption.SNDTIMEO, 100.msecs); s.connect(ia); sockets[i] = s; } for (int i = 0; i < TRIES; i++) { ss.reset(); foreach (s; sockets) { if (s !is null) ss.add(s); } int status = Socket.select(null, ss, null, 100.msecs); if (status > 0) { for (int j = 0; j < sockets.length; j++) { if (sockets[j] !is null && ss.isSet(sockets[j])) { try { writeln(sockets[j].remoteAddress().toString()); ss.remove(sockets[j]); sockets[j].close(); sockets[j] = null; } catch { } } } } Thread.sleep(50.msecs); } }
Mar 26 2016