[Solved] Merkwürdiges Problem mit QProcess

Alles rund um die Programmierung mit Qt
Antworten
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

[Solved] Merkwürdiges Problem mit QProcess

Beitrag von daniel_23 »

Hi, ich hab Probleme mit QProcess!
Ich hab ein Programm in dem ich zwei Buttons hab die jeweils einen QProcess ausfuehren. Der eine funktioniert und der andere nicht, und das scheint irgendwie am Kommando zu liegen! Auf dem einen Button ist ein "whois $ip" Befehl der wunderbar funktioniert, auf dem anderen ein "nmap $ip" was nicht funktioniert, warum auch immer.
Hier mal der Code:

Code: Alles auswählen

			QProcess process;
			process.setReadChannelMode(QProcess::MergedChannels);

// 			Wuerde ohne probleme klappen
// 			process.start("whois" ,  QStringList() << ip);

// 			Funzt aus mir unbekannten Gruenden nicht!
			process.start("nmap -v -F" ,  QStringList() << ip);

			if (!process.waitForStarted())
				PaintArea("Error while starting the process");
			else if (!process.waitForFinished())
				PaintArea("Error while finishing the process");
			else
				PaintArea(process.readAll( ));
Jedesmal geht der in die erste if Abfrage rein, also dann scheint der Prozess garnicht gestartet worden zu sein.

Als system() Befehl funktioniert auch nmap ohne Probleme, aber den hatte ich ja grad erst ausgebaut wegen QProcess, und eigentlich sollte der da auch nich nochmal rein!

Auf jedenfall ne merkwuerdige Sache, vielleicht kann mir ja jemand bei dem problem weiterhelfen!

Grad nochmal "ping -c 1 " ausprobiert, klappt auch nich!
wo liegt nur das Problem?
Zuletzt geändert von daniel_23 am 22. Mai 2006 09:36, insgesamt 1-mal geändert.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

nmap ist eben ein verdamt langen process...

process.start("nmap -v -F" , QStringList() << ip);
und so ist es sicher falsch...

das programm ist nmap ... also...
######## programmname#######parameter###########
process.start("nmap" , QStringList() << "-v" << "-F" << ip); /*ip is variable*/

fuer deine zwecke empfehle ich dir eine liste aufzustellen mit alle gaengigen port...

auch externes file ... am ende kannst es auch als resource integrieren... und immer wieder aendern wenn ein neuen port da ist....

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<scanport>
 <continue port="80" name="www"  type="tcp" timeout="1500" />
 <continue port="25" name="smtp" type="tcp" timeout="1500" />
 <continue port="21" name="ftp" type="tcp" timeout="1500" />
 <continue port="22" name="xxx" type="tcp" timeout="1500" />
 <continue port="3036" name="mysql" type="tcp" timeout="1500" />
</scanport>
mit QDomDocument auslesen .. und mit socket abfragen ... oder mit libcurl .... http://curl.haxx.se/ geht noch einfacher...

so kanst du einstellen das die erste wichtige port am anfang gemacht werden un bereit angezeigt werden .... und dann immer appenden in der textarea..... sonst bekommt man ewig nichts zu sehen....

Und zweitens zu deinem vorteil machst du ein programm das auf alle os laufen....... da sich libcurl auf jedem os installieren laest.. und schnell noch dazu......
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Cool besten Dank fuer deine Hilfe!
Hat wunderbar geklappt, deine Tips sind auch gut, mal demnaechst einbauen..

Nochmal Danke!
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

patrik08 hat geschrieben:und dann immer appenden in der textarea..... sonst bekommt man ewig nichts zu sehen....
also mit dem updaten der Textarea hab ich grad so meine Probleme!

Zuerst hab ich das ja so gemacht:

Code: Alles auswählen

result_all->insertPlainText(TEXT2);
Doch so wird die Textarea auch nich upgedated solange das Programmr aktiv ist:

Code: Alles auswählen

result_all->append(TEXT2);
Ich hab mir sogar nen weiteren SLOT erstelt, der in dem aufgerufennen SLOT aufgerufen wird :-)
hat aber nichts leider gebracht :-(

Wie ist das genau gemeint mit dem appenden, damit die Textarea upgedated wird?

Also ich hab jetz beispielsweise ein "ping -c 1 $ip" command, der in einer whileschleife aufgerufen wird, also beansprucht das Kommando ansich nicht die ganze Zeit die das Programm inaktiv ist.
Der Befehl "result_all->append(TEXT2);" wird nach jedem einzelnen Ping ausgefuehrt, aber erst nach dem letzten wird alles angezeigt.

Waere nett wenn mal wieder einer helfen koennte!

Jetz versuch ich schon seid einiger Zeit die SIGNALS von QProcess mit selbstr erstellten SLOTS zu connecten, bisher ohne Erfolg
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Also jetz bin ich schon ein gutes Stueck weiter!
Aber nen Problem hab ich immer noch:
Der ich habe einen eigenen Slot der durch ein SIGNAL von QProcess ausgefuehrt wird:

Code: Alles auswählen

connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(ready())); 
hier ist die Definition des SLOTS:

Code: Alles auswählen

void KscanMain::ready(){
	printf("Ready");
	if(!process.waitForFinished())
		printf("ERROR\n");
	else {
		strcpy(TEXT2,strstr(qtchar(process.readAll()),"64"));
		result_all->append(TEXT2);
	}
}
der Prozess wird aus einer while Schleife in einem anderen SLOT ausgefuehrt:

Code: Alles auswählen

void KscanMain::ping()
{
	/* get QString from QLineEdid */
	QString ip = ip_from_user->text(); 

        if( ip_from_user->text().length() > 7 ){

		/* QString in Char */
		strcpy(IP,qtchar(ip));

		/*	Check if Input is an IP	*/
		if( matchip(IP,"([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})") == 0)
			wronginput();
		else {
		if (ip.size() > 0) {
			process.setReadChannelMode(QProcess::MergedChannels);

			strcpy(IP,"");
			strcpy(TEXT2,"-c ");

			char tries[32];
			sprintf(tries, "%d", pingTries->value());
			strcat(TEXT2, tries);

			result_all->clear();

			int x=0;
			while(x != pingTries->value()){
				if(!process.waitForFinished() && x != 0)
					printf("hrrrr\n");
				else
					process.start("ping" , QStringList() << "-c 1" << ip);
				x++;
			}
		}}
	}
	else
		wronginput();
}
"pingTries" is ein Inputfeld mit dem ich die Anzahl der Ping Versuche defeniere.
Wenn dies auf 1 steht funktioniert alles wie erwartet, bei allen hoeheren Zahlen greift der folgende Abschnitt des ready() SLOTs:

Code: Alles auswählen

if(!process.waitForFinished())
		printf("ERROR\n");
lasse ich diese Abfrage weg krieg ich auch nen Error

Ich versteh nich so ganz was da jetz bei mir falsch ist!
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

gibt doch einen zeitlimit an qprocess..

bei limit oder result
..... appenden...
result_all->append(TEXT2);

Herr Ping ... der erfinder von ping .... Michael John Muuss ist im dezember 2000 gestorben im jungen alter von 38 jahren ruhe er in frieden...

In der heutige zeit mit firewall ... iptable ecc... gibt es doch auf linux bessere und vorallem sichere methoden um zu sehen ob ein ip up ist...... ecc...

Wie bereits gesagt nimm einfach libcurl ... dort bekommst du noch mehr info zur port... http header server sistem os software zeit cookie ecc... besser gesagt 50 mal mehr info op ein server ub ist oder nicht...

Und du kannst einstellen den zeitlimit fuer di abfrage und das result abfragen...
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Danke fuer die schnelle Antwort!
wegn libcurl, das schau ich mir auf jeden fall noch an, bloz das is mein erstes QT Programm, und atm brauch ich noch viele Grundlagen, dann wieder mit was anderem beschaeftigen, moecht ich momentan nich.
Das ist ja auch eher ein generelles Problem, ich hab noch nen nmap SLOT bei dem ist das selbe...

Das mit dem Zeitlimit hilft irgendwie auch nicht :-( :

Code: Alles auswählen

	if(!process.waitForFinished(999999999))
		printf("ERROR\n");
und ich krieg noch die Error Nachricht, oder wie war das mitm TimeOut gemeint?
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

Was hast du den vor qt gemacht .. wenn ich fragen darf .... denke nicht dass ich qt spezialist bin... ich kenne qt seit 2 monaten... als ich eine qt3 pdf buch auf eine zeitschrift gefunden (ist immer noch dort http://ppk.ciz.ch/qt_c++/ ) habe seit dem datum versuche ich c & qt (Habe auch nur 3-4 programme gemacht ... dass letzte ist auf sf.net gelandet .. http://sourceforge.net/projects/qtexcel-xslt/ ) jedoch kenne ich php seit 10 jahren von anfang an vo es noch php2 gab mit phtml....

hast du java erfahrung ... oder html ... und wass sonst noch...
Ich denke dass wenn man solche programme macht ... dann von anfang an das beste daraus machen... und nicht mit qprocess andere programme vergewaltigen ... am ende bist du unzufrieden wenn es zu langsam ist...
lieber das programm modular aufbauen .. mit wenigen funktionen ... aber eben schnell... wenn auf ein port innert 2 sekunden nichts kommt... ist es garantiert zu ... oder ein firewall ist aktiv...
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Ich weiz schon, den system befehl will ich ja auch meiden, aber darum geht es jetz wie gesagt garnicht!

Waere nett wenn du bei dem Problem von QProcess weiterhelfen koenntest, aber wie ich das Programmieren angehe bleibt mir ueberlassen, und ich mach das jetz so!

Ich hab jetz ja schon das meiste des relevanten Codes gepostet, irgendwo da is nen fehlker drin und ich find ihn nich!

Ich glaube es ist die while Schleife die den System Befehl verschieden oft aufruft, und immer gefangen ist. Waehrrenddessen werden keine weiteren SLOTS ausgefuehrt

EDID: Jippii endlich geschafft!! Ich poste gleich wenn ich fertig bin auch mal den Code
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Das lag wie vermutet an der while Schleife!
Also hier mal der Code falls jemand mal das selbe problem hat:

Code: Alles auswählen

void KscanMain::ready(){
	process.setReadChannelMode(QProcess::MergedChannels);
	strcpy(TEXT2,qtchar(process.readAll()));
	result_all->append(TEXT2);
	process.close();
usleep(200);
	if(fin+2 <= pingTries->value()){
		ping();
	}
	fin++;
}

Code: Alles auswählen

void KscanMain::ping()
{
	QString ip = ip_from_user->text(); 

        if( ip_from_user->text().length() > 7 ){

		strcpy(IP,qtchar(ip));

		if( matchip(IP,"([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})") == 0)
			wronginput();
		else if (ip.size() > 0) {
			strcpy(IP,"");
			strcpy(TEXT2,"-c ");

			char tries[32];
			sprintf(tries, "%d", pingTries->value());
			strcat(TEXT2, tries);
				process.start("ping" , QStringList() << "-c 1" << ip);
				if(!process.waitForFinished(-1))
					QMessageBox::information( this , "Error while running Ping!", process.errorString() );
		}
	}
	else
		wronginput();
}
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Hat nicht direkt mit dem Thema zu tun, aber als ich das hier sah, musste ich einfach antworten :-)
daniel_23 hat geschrieben:

Code: Alles auswählen

if( matchip(IP,"([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})") == 0)
Eine IP zu prüfen ist nicht ganz einfach. Hier eine kleine Erklärung warum und wieso und wie man es am besten hin bekommt:
http://www.regular-expression.info/examples.html
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

Yeah cool besten dank!
Das war eines der naechsten Sachen die ich machen wollte, das nur 0.0.0.0-255.255.255.255 matched.
Ich guck mir die Site gleich mal an!

Es ist allerdings immer das selbe Problem mir Regex: Die Syntax ist nicht Allgemneingueltig!
ich hab zwar jetzt den hier auf der Site gefunden:

Code: Alles auswählen

\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
Aber c syntax ist das nich!
keine Ahnung wie ich den auf c Syntax umaendern muss, wenn du das mal ebn rausschuetteln kannst, hau rein :-)
Ansonsten wird das ein ewig langes rumprobiere heute, denk ich.

So klappt es jedenfalls nicht:

Code: Alles auswählen

if( matchip(IP," (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)") == 0)
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

daniel_23 hat geschrieben:Es ist allerdings immer das selbe Problem mir Regex: Die Syntax ist nicht Allgemneingueltig!
Regular Expressions haben eine eigene Syntax, das hat nichts mit C zu tun. Ich weiß nicht auf was für Probleme Du dich jetzt beziehst, ich hatte dahin gehend noch keine.
daniel_23 hat geschrieben:keine Ahnung wie ich den auf c Syntax umaendern muss, wenn du das mal ebn rausschuetteln kannst, hau rein :-)
Ich bin auch nicht der Expression-Held und hätte mich wohl auf die kurze Variante beschränkt. Danach den String in seine Teilnummern splitten und die auf Größe prüfen. So könnte man auch IP-Bereiche raus nehmen, falls das nötig ist.
daniel_23
Beiträge: 46
Registriert: 15. Mai 2006 18:53
Wohnort: Oldenburg
Kontaktdaten:

Beitrag von daniel_23 »

So heut morgn mal rangesetzt, und so schwer is das garnich :-)
Hier mal der regex.h code fuer IPs:

Code: Alles auswählen

			/* 0.0.0.0-255.255.255.255 */
			if( matchip(IP, 	"(^[2]{0,1}[5]{0,1}[0-5]{1,1}|^[2]{0,1}[0-4]{0,1}[0-9]{1,1}|^[0-1]{0,1}[0-9]{0,1}[0-9]{1,1})\\."
						"([2]{0,1}[5]{0,1}[0-5]{1,1}|[2]{0,1}[0-4]{0,1}[0-9]{1,1}|[0-1]{0,1}[0-9]{0,1}[0-9]{1,1})\\."
						"([2]{0,1}[5]{0,1}[0-5]{1,1}|[2]{0,1}[0-4]{0,1}[0-9]{1,1}|[0-1]{0,1}[0-9]{0,1}[0-9]{1,1})\\."
						"([2]{0,1}[5]{0,1}[0-5]{1,1}$|[2]{0,1}[0-4]{0,1}[0-9]{1,1}$|[0-1]{0,1}[0-9]{0,1}[0-9]{1,1}$)") == 0)
Antworten