PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Qt] Problem mit QSocket



tuxipuxi
21-04-2003, 14:46
hallo Leute,

ich wollte mal QSocket ausprobieren und hab mir als testobjekt einen super-simpel portscanner ausgesucht.
das Programm laueuft, nur nich wie es soll. es gibt keine offenen ports aus sondern bleibt stumm.

im anhang ist die .tar.gz mit makefile und so. (von .txt in .tar.gz umbennen)


danke im vorraus,

tuxipuxi.

edit:

die ist zu gross... ihr findet sie unter:
http://tuxipuxi.homelinux.org/public/portscan-0.1.tar.gz
leider nicht den ganzen tag on.

axeljaeger
21-04-2003, 21:01
keine Komplettlösung, aber ich bin schon ziemlich weit, finde ich.
Ich hab auf QWidget umgestellt, weil ich glaube, dass Qt Netzwerk erst geht, nachdem die Mainloop mit app.exec
gestartet wurde.



<b>main.cpp</b>
#include <qapplication.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

#include "scan.h"


int main( int argc, char* argv[] )
{
// Starte mal portscan <deineIP> 79 81
// und drück ein paar mal den Knopf, dann solle dein Webserver schon gefunden werden
if( argc!=4 ) { cout<<"Usage: "<<argv[0]<<" <host> <startport> <endport> "<<endl; exit(0); }


QApplication app( argc, argv );

Scan scano( argv[1],atoi(argv[2]),atoi(argv[3]) ); // <-- Das sollte kein Pointer sein, wer löscht den denn?
app.setMainWidget(&scano);
scano.resize(120,100);
scano.show();

return app.exec();

}



<b>scan.h</b>
#ifndef SCAN_H
#define SCAN_H

/// #include <qobject.h>

#include <qwidget.h>

class QSocket;



class Scan : public QWidget {
Q_OBJECT

public:
Scan(const char* hostname, int start, int end);


private:
QString _hostname;
int _start, _end;

QSocket *socket;


private slots:
void scanPorts();
void portOpen();
};

#endif




<b>scan.cpp</b>
#include <qsocket.h>
#include <qstring.h>
#include <iostream>
#include <cstdio>
#include <qpushbutton.h>


using namespace std;

#include "scan.h"



Scan::Scan( const char* hostname, int start, int end ) : QWidget(0,0), _hostname(hostname), _start(start), _end(end)
{

socket = new QSocket( this );

QString host( hostname );

cout<<"Starting Scan on "<<_hostname.latin1()<<" from "<<start<<" to "<<end<<endl;

connect( socket, SIGNAL( connected() ), this,SLOT( portOpen() ) );

//scanPorts( host, startport, endport );
QPushButton* btnScan = new QPushButton("Scan !", this);
connect( btnScan, SIGNAL( clicked() ), this,SLOT( scanPorts() ) );
}

void Scan::scanPorts( ) {

for( Q_UINT16 port=_start; port < _end; ++port ) {

socket->connectToHost( _hostname, port ); // <-- Ich nehme an, das du dir hier die Verbindung gleich wieder kaputt haust
cout<<"trying to connect to " <<_hostname.latin1()<<":"<<port<<endl;
}
}


void Scan::portOpen() {

//printf("%uh ist open\n", socket->port());
cout << (socket->port()) << " is open" <<endl; // <-- Hier kommen Fantasiezahlen raus
}

tuxipuxi
22-04-2003, 08:24
hi,

danke fuer antwort.

ich verstehe aber nicht so ganz den vorteil deiner loesung, sie tut ja genau das gleiche wie meine, naemlich nicht das was sie soll.

wenn du recht hast, dass Qt Network nur mit zusammenarbeit mit QWidget klappt waere das aber ein ziemliches armutszeugnis... es gibt ja auch bestimmt Qt Apps, die konsolenanwendungen sind.

anda_skoa
22-04-2003, 09:23
Original geschrieben von tuxipuxi
wenn du recht hast, dass Qt Network nur mit zusammenarbeit mit QWidget klappt waere das aber ein ziemliches armutszeugnis... es gibt ja auch bestimmt Qt Apps, die konsolenanwendungen sind.

Braucht man auch nicht.
Man braucht für QSocket nur die Eventloop, also eine laufende QApplication Instanz.

Steht in unsere Qt Tutorial :D

Dem QApplication Konstruktor als drittes Argument false übergeben, damit es eine Consolen Anwendung wird.

Ciao,
_

axeljaeger
22-04-2003, 17:10
Nein, stimmt nicht, dass das genau das gleiche ist. Mir ist aufgefallen, das connectToHost asyncron ist, also zurückkehrt, bevor die Verbindung aufgebaut wurde. Wenn du jetzt während du auf die alte Verbindung wartest, dem QSocket eine neue Verbindung aufgibst, haust du die alte Verbindung kaputt, deswegen geht das im Moment nur, wenn der letzte Port ein offener Port ist

Edit:

Ich denke, du kommst nicht drumrum, für jede Verbindung einen eigenen QSocket zu verwenden. Ein Array wäre wohl geeignet, ich weis nur nicht, wie viel Overhead das mit sich bringen würde -> ausprobieren

anda_skoa
23-04-2003, 19:26
Original geschrieben von axeljaeger

Mir ist aufgefallen, das connectToHost asyncron ist, also zurückkehrt, bevor die Verbindung aufgebaut wurde.


Ja, das ist ja das feine an QSocket. Man hat dann ein Signal, wenn der Connect tatsächlich erfolgt ist.
Wäre schön unangenehm, wenn connectToHost blockieren würde, da diese Methode ja häufig als Resultat eines Userinputs (Klick, etc) passiert.

Ciao,
_

TheDodger
29-04-2003, 08:15
Original geschrieben von anda_skoa
Ja, das ist ja das feine an QSocket. Man hat dann ein Signal, wenn der Connect tatsächlich erfolgt ist.
Wäre schön unangenehm, wenn connectToHost blockieren würde, da diese Methode ja häufig als Resultat eines Userinputs (Klick, etc) passiert.

Nun, es ist nicht immer so fein ... jedenfalls nach meiner Erfahrung.
Ich brauchte ja etwas ähnliches ... als Konsolenanwendung und da ist dieses asyncrone Design manchmal wirklich nervig.

z.B. meine eventLoop wurde schon beendet bevor ein Connect zum Server aufgebaut war. und damit hatte sich das ganze Programm schon sauber verabschiedet ...
Dann das ganze in Klassen gekapselt ... da hat es funktioniert, doch das Programm rannte in einer Endlosschleife und wurde gar nicht mehr beendet ...

anda_skoa
29-04-2003, 09:58
Original geschrieben von TheDodger
Nun, es ist nicht immer so fein ... jedenfalls nach meiner Erfahrung.
Ich brauchte ja etwas ähnliches ... als Konsolenanwendung und da ist dieses asyncrone Design manchmal wirklich nervig.


Ich hab auch schon in Konsolenanwendungen Eventloop benutzt.
Aber wenn du es Blocking brauchst, kannst du auch QSocketDevice benutzen.
Das benutzen wir in der Firma, wenn wir mir Threads arbeiten.

Ciao,
_