Checking if a port is listening

Lucien via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Mar 19 02:55:13 PDT 2016


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 ?


More information about the Digitalmars-d-learn mailing list