March 23, 2016 Re: Checking if a port is listening | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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 ?
|
March 24, 2016 Re: Checking if a port is listening | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lucien | 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.
|
March 24, 2016 Re: Checking if a port is listening | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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..
|
March 26, 2016 Re: Checking if a port is listening | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lucien | 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); } } |
Copyright © 1999-2021 by the D Language Foundation