select() mit Microsekunden-Timeout

saftmeister

Nutze den Saft!
Hallo,

folgender Code:

C++:
struct timeval timeout;
timeout.tv_sec = 2;

if(tim > 50 && tim < 120 * 1000) // tim ist ein int und kommt als Benutzer-Eingabe
{
  timeout.tv_sec = 0;
  timeout.tv_usec = tim * 1000 * 1000;
}

select(......, timeout);

Anscheinend werden die Microsekunden-Angaben vollkommen ignoriert. Kann mir jemand sagen, was ich falsch mache?
 
Woher weißt du, dass die Mikrosekunden ignoriert werden bzw. wie ist die Funktion select definiert?
 
Hallo,

kannst du mal ein Minimalbeispiel posten was bei dir nicht tut? Welches Betriebssystem verwendest du? In Linux liegt die Timerauflösung für select AFAIK im Jiffies Bereich. D.h. ist dein Linuxkernel bspw. mit HZ=250 kompiliert würde select mit einer Auflösung von 4ms arbeiten...

Gruß,
RedWing
 
Wieso lässt du werte >= 1000 für "tim" zu? Dann solltest du vielleicht sowas machen:
C:
timeout.tv_sec = tim / 1000;
timeout.tv_usec = (tim % 1000) * 1000 * 1000;

Und wenn ich mich recht erinnere, erwartet select einen pointer auf ein timeval. also select(..., &timeout);
 
Ok, hier ist der komplette Code:

<Code aus rechtlichen Gründen entfernt>

Und falls hier einer denkt, das wäre illegal: Das Tool soll in der Firma eingesetzt werden um zu prüfen, ob von bestimmten Rechnern bestimmte Ports erreichbar sind für Monitoring- und Debugging-Zwecke :-)
 
Zuletzt bearbeitet:
Und falls hier einer denkt, das wäre illegal: Das Tool soll in der Firma eingesetzt werden um zu prüfen, ob von bestimmten Rechnern bestimmte Ports erreichbar sind für Monitoring- und Debugging-Zwecke :-)
Und wieso verwendet ihr dazu nicht einfach ein frei verfügbares, ausgiebig getestetes Tool wie Nmap? Hast du abgesehen davon den Vorschlag von OnlyFoo schon ausprobiert?

Grüße,
Matthias
 
Und wieso verwendet ihr dazu nicht einfach ein frei verfügbares, ausgiebig getestetes Tool wie Nmap?

Weil das nicht gestattet wird. Wir hätten dafür genauso gut telnet verwenden können, wenn es gestattet wäre, es zu installieren. Das bekommt man nicht durch die Security-Abteilung...


Hast du abgesehen davon den Vorschlag von OnlyFoo schon ausprobiert?

Ja hab ich. Es war mir gleich klar, das es nicht funktioneren kann. tv_sec ist vom Typ long, das Teilen von 500 durch 1000 kommt nach Adam Riese auf 0,2, was durch den long-Typ auf 0 gesetzt wird. Der restliche Teil der Kalkulation macht nur eines: das Resultat verfälschen. Hier mal ein Beispiel (moon ist mein Test-Host):

EDIT: Das Resultat wird nicht verfälscht, ich ziehe diese Aussage zurück. Aber das Resultat sollte das gleiche sein, wie mein erster Code.

Code:
[root@localhost ~]# time { ./porttest -i moon -p 90 -v -t 500; }
resolved address: 192.168.178.33
timeout is 0 seconds, 500000000 useconds
Connection refused

real    0m1.008s
user    0m0.000s
sys     0m0.006s

[root@localhost ~]# time { ./porttest -i moon -p 80 -v -t 500; }
resolved address: 192.168.178.33
timeout is 0 seconds, 500000000 useconds
Success

real    0m0.018s
user    0m0.001s
sys     0m0.005s

[root@localhost ~]# time { ./porttest -i moon -p 80 -v -t 250; }
resolved address: 192.168.178.33
timeout is 0 seconds, 250000000 useconds
Success

real    0m0.021s
user    0m0.000s
sys     0m0.006s

[root@localhost ~]# time { ./porttest -i moon -p 90 -v -t 250; }
resolved address: 192.168.178.33
timeout is 0 seconds, 250000000 useconds
Connection refused

real    0m1.009s
user    0m0.000s
sys     0m0.007s

Das ist übrigens mit dem Code von onlyfoo getestet. EDIT: Port 80 ist erreichbar, Port 90 nicht.

Grüße und trotzdem Danke an alle, ich hab so langsam das Gefühl, das kann derart nicht gelöst werden. Ich werde mir mal pselect() ansehen.
 
Zuletzt bearbeitet:
Okay hab deinen Fehler.
tim ist bereits in Milisekunden, also muss nur noch mit 1000 multipliziert werden, um Mikrosekunden zu erhalten:
C:
if(tim >= MINIMAL_CONNECTION_TIMEOUT && tim <= MAXIMAL_CONNECTION_TIMEOUT)
        {
          timeout.tv_sec = tim / 1000;
          timeout.tv_usec = (tim % 1000) * 1000;
        }

Und 500 / 1000 ist übrigens nicht 0.2... Und die Rechnung macht schon sinn. Spiel das mal für tim = 2500ms durch
olli@laptop:/tmp$ time ./a.out -i google.de -p 1234 -v -t 2500
resolved address: 209.85.229.104
timeout is 2 seconds, 500000 useconds
Connection timed out

real 0m2.525s
user 0m0.000s
sys 0m0.000s
 
Du hast recht, ich hab mich bei den Einheiten verhaspelt. Außerdem hast du recht, es sind 0,5 ;-)

Desweiteren habe ich mich schon korrigiert, deine Rechnung ist korrekt.

Danke also noch mal...
 
Zurück