Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: C++ (auch C++0x und C++11) ::  netcat mit c++ bedienen  
Gehen Sie zu Seite Zurück  1, 2, 3, 4, 5, 6  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Belli
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2009
Beiträge: 1773
Beitrag Belli Mitglied 00:39:30 12.05.2012   Titel:              Zitieren

Okay, das Problem habe ich glaube ich verstanden, warum das so ist, weiß ich nicht.
Es könnte aber sein, dass das Schreiben in die Datei nur deshalb beginnt, weil das zugehörige myConsole - Objekt zerstört wird. Wenn es Dich nicht stört, dass Du danach keine Kontrolle mehr über das gestartete netcat hast, könntest Du das ja mal versuchen, indem Du das myConsole - Objekt in einem Scope erzeugst, Deine Befehle an netcat absetzt, und dann den Scope verlässt und beobachtest, ob jetzt die Datei gefüllt wird.
Belli
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2009
Beiträge: 1773
Beitrag Belli Mitglied 01:34:44 12.05.2012   Titel:              Zitieren

Ich habe gerade einen kleinen Test gemacht:
Folgendes Testprogramm
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <windows.h>
#include <iostream>
 
using namespace std;
 
int main()
{
    while(++i < 1000000)
    {
        cout << "chrrrrrr ...\n";
        Sleep(300);
    }
}


via
C++:
mc.doCommand("test > test.txt");
gestartet und dann einfach mal abgewartet. Es ist nicht so, dass in die test.txt nicht geschrieben wird, es dauert einfach eine Weile, bis das Testprogramm seine Buffer mal flusht. Auch das Startprogramm lief noch, das myConsole - Objekt existierte noch, und nach einer ganzen Weile wurde die test.txt dann doch mal gefüllt. Vermutlich muss erst eine ganze Menge Daten zum Schreiben angefallen sein. Keine Ahnung, ob man das Buffer flushen von außen beeinflussen kann ...
jasdefer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.05.2012
Beiträge: 29
Beitrag jasdefer Mitglied 15:24:40 12.05.2012   Titel:              Zitieren

hm wielange hat es denn bei dir gedauert? ich hab jetzt schonmal n paar mins gewartet und es ist trotzdem nichts in der txt datei erschienen. erst als ich das haupptfenster wieder geshclossen habe.

wie würde ich denn das myconsole objekt in einem scope erzeugen?
Belli
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2009
Beiträge: 1773
Beitrag Belli Mitglied 12:37:30 13.05.2012   Titel:              Zitieren

jasdefer schrieb:
hm wielange hat es denn bei dir gedauert? ich hab jetzt schonmal n paar mins gewartet und es ist trotzdem nichts in der txt datei erschienen. erst als ich das haupptfenster wieder geshclossen habe.

wie würde ich denn das myconsole objekt in einem scope erzeugen?

Mit meinem og Testprogramm wurde das erste Mal in die txt-Datei geschrieben, als etwa 350 Zeilen erzeugt waren.

Eine Variable in einem Scope erzeugen? Na, entweder in einer Funktion, oder so:

...
{
myConsole mc;
...
}

Wenn die Funktion beendet wird, oder im obigen Fall die schließende Klammer erreicht wird, wird mc zerstört und der Destruktor aufgerufen.
Hat bei meinen Experimenten aber nix gebracht ...
jasdefer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.05.2012
Beiträge: 29
Beitrag jasdefer Mitglied 08:21:20 14.05.2012   Titel:              Zitieren

ich hab auch noch einmal das programm ausgeführt und sehr viel text übertragen lassen. mehr als 350 zeilen. trotzdem wurde die txt datei nicht aktualisiert.

ach das ist mit scope gemeint. das habe ich auch noch einmal probiert, hat aber leider auch nicht funktioniert.

Fällt dir noch eine möglichkeit ein, wie man das Problem lösen könnte? Das würde mir sehr doll helfen
jasdefer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.05.2012
Beiträge: 29
Beitrag jasdefer Mitglied 08:26:14 14.05.2012   Titel:              Zitieren

ach noch etwas interessantes. Wenn ich das netcat lauschen mit strg+c beende und das hauptfenster schließe wird die textdatei garnichtmehr aktualisiert. also wenn ich mit strg+c die verbindung beende, gehen die informationen die in die txt datei geschrieben werden sollen verloren :/
Belli
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2009
Beiträge: 1773
Beitrag Belli Mitglied 08:41:58 14.05.2012   Titel:              Zitieren

Ja, ist aber etwas mehr Aufwand. Du könntest zusätzlich zur Umleitung des StandardEingabeStroms auch noch den StandardAusgabeStrom umleiten. Ich habe für so einen Zweck vor kurzem eine Klasse im Konsolen-Forum vorgeschlagen, die habe ich auch als Vorlage für die hier gezeigt genommen.
Allerdings wird die für Deine Zwecke so nicht funktionieren, weil Dein netcat-Programm nicht zu Ende läuft, sondern weiter aktiv bleiben soll.
Du müsstest also ganz grob:
- eine zweite Pipe für die Umleitung des Standard-Ausgabe-Stroms erstellen
- das write-Handle dieser Pipe an den erzeugten Prozess (netcat) vererben
- und in Deinem Programm einen zweiten Thread starten, der sich um das Lesen/Verarbeiten der Ausgabe von netcat kümmert.

Sieh Dir also nochmal die Klasse myConsole und die Klasse mySystem aus dem Konsolen-Forum an, versuch die Geschichte mit dem Umleiten der Standard-Eingabeströme zu recherchieren und zu verstehen, und sieh Dir an, wie das mit dem Thread funktioniert.

Wenn Du dann noch Detail-Fragen hast, stell sie ruhig hier. Ein schönes kurzes Beispiel für die Redirektion von STDIN und STDOUT gleichzeitig findest Du z.B. hier:
http://msdn.microsoft.com ....... s682499%28v=vs.85%29.aspx
Allerdings brauchst Du für Deinen konkreten Fall wie gesagt einen zweiten Thread, obwohl, vielleicht geht es auch so, wenn Du zuerst Deine Befehle an netcat absetzt, und dann beginnst, den Output zu lesen und zu verarbeiten, ja, es hängt halt von den konkreten Anforderungen ab. Sieh Dir das Beispiel aus der MSDN an, vielleicht reicht Dir das schon, wenn Du es ein wenig anpasst.

Edit:
Du würdest bei dieser Variante also keine Datei mehr schreiben, sondern die netcat-Ausgaben direkt in Deinem Hauptprogramm lesen.


Zuletzt bearbeitet von Belli am 08:43:31 14.05.2012, insgesamt 1-mal bearbeitet
jasdefer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.05.2012
Beiträge: 29
Beitrag jasdefer Mitglied 09:32:27 14.05.2012   Titel:              Zitieren

okay, dann werde ich das mal probieren. vielen dank :) ich guck mir das alles mal genauer an und versuhch die einzelnen schritte zu vertsehen
jasdefer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.05.2012
Beiträge: 29
Beitrag jasdefer Mitglied 10:05:22 14.05.2012   Titel:              Zitieren

müsste ich, soweit ich das verstanden hab, dann im endeffekt zwei pipes haben. also pipe.h und pipe2.h zB. eben einmal für die umleitung der eingabgeströme eins und eins für die ausgabeströme?
Belli
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2009
Beiträge: 1773
Beitrag Belli Mitglied 10:48:03 14.05.2012   Titel:              Zitieren

Zwei Pipes ja, aber nicht pipe1.h und pipe2.h ...
Probier mal folgendes(pipe.h und pipe.cpp bleiben wie gehabt):
Das hab ich jetzt nur mal auf die Schnelle so hingerotzt, aber für das Testprogramm funktioniert es:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef MYCONSOLEH
#define MYCONSOLEH

#include <string>

#include "pipe.h"
 
class myConsole
{
    public:
        myConsole();
        void doCommand(std::string command);
        std::string readFromProcess();
   
    private:
   
        pipe writePipe;
        pipe readPipe;
       
        void startCommandProcess(HANDLE wrHandle, HANDLE rdHandle);
};

 
#endif

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include "myConsole.h"
 
 
//public
 
myConsole::myConsole()
{
    writePipe.MakeInheritable(pipe::READ);
    readPipe.MakeInheritable(pipe::WRITE);
   
    startCommandProcess(readPipe.GetPipeHandle(pipe::WRITE), writePipe.GetPipeHandle(pipe::READ));
   
    writePipe.ClosePipeHandle(pipe::READ);
    readPipe.ClosePipeHandle(pipe::WRITE);
   
   
}
 
 
void myConsole::doCommand(std::string command)
{
    DWORD ignore;
   
    command.append("\n");
    WriteFile(writePipe.GetPipeHandle(pipe::WRITE), command.c_str(), command.size(), &ignore, 0);
}
 
std::string myConsole::readFromProcess()
{
   char inBuf[256];
   DWORD nBytesRead = 0;
    std::string tmp;
 
    ReadFile(readPipe.GetPipeHandle(pipe::READ), inBuf, 256, &nBytesRead, NULL);
    return std::string(inBuf, nBytesRead);
 
/*
   while(TRUE)
   {
      if (!ReadFile(readPipe.GetPipeHandle(pipe::READ), inBuf, 256, &nBytesRead, NULL) || !nBytesRead)
        break;
     
      for(int i = 0; i < nBytesRead; ++i)
      {
        if(inBuf[i] == 10)
        {
            result.push_back(tmp);
            tmp.clear();
        }
        else if(inBuf[i] == 13)
            ;
        else
            tmp.push_back(inBuf[i]);
      }
   }   
*/

}
 
//private
void myConsole::startCommandProcess(HANDLE wrHandle, HANDLE rdHandle)
{
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
 
   // Set up the start up info struct.
   ZeroMemory(&si,sizeof(STARTUPINFO));
   si.cb = sizeof(STARTUPINFO);
   si.dwFlags = STARTF_USESTDHANDLES;
   si.hStdInput = rdHandle;
   si.hStdOutput = wrHandle;
   si.hStdError  = wrHandle;
 
   // Use this if you want to hide the child:
   //   si.wShowWindow = SW_HIDE;
   // Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
   // use the wShowWindow flags.
 
 
   // Launch the process that you want to redirect (in this case,
   // Child.exe). Make sure Child.exe is in the same directory as
   // redirect.c launch redirect from a command line to prevent location
   // confusion.
   
   CreateProcess(NULL, "cmd", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
 
   // Close any unnecessary handles.
   CloseHandle(pi.hThread);
   CloseHandle(pi.hProcess);
}

Testprogramm:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include "myConsole.h"
 
using namespace std;
 
 
 
int main()
{
    myConsole mc;
   
    //einige Kommandos absetzen, bei Dir zB "netcat ..." usw.
    mc.doCommand("dir");
    mc.doCommand("ipconfig");
    mc.doCommand("attrib");
   
    //Ab hier die Ausgaben lesen und verarbeiten, hier werden sie einfach
    //via cout auf die Konsole geschrieben
    string str;
    do
    {
        str = mc.readFromProcess();
       
        cout << str;
    }while(str.size());
}


Edit:
Nachteil bei dieser threadlosen Lösung ist, wenn der gestartet Prozess nichts mehr schreibt, bleibt das Programm in readFromProcess hängen.


Zuletzt bearbeitet von Belli am 10:55:31 14.05.2012, insgesamt 1-mal bearbeitet
c++.de :: C++ (auch C++0x und C++11) ::  netcat mit c++ bedienen  
Gehen Sie zu Seite Zurück  1, 2, 3, 4, 5, 6  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.