Checking if a port is listening

Lucien via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Mar 23 14:37:09 PDT 2016


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 
?


More information about the Digitalmars-d-learn mailing list