kostenloser Webspace werbefrei: lima-city


FTP Server selbst programmieren

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    tangoal

    Kostenloser Webspace von tangoal

    tangoal hat kostenlosen Webspace.

    Hallo Leute,

    ich möchte mal wieder was spannendes mit C/C++ (zusätzlich Qt-Bibliotheken) tun. Ein FTP Client Programm zu schreiben ist relativ einfach. Dafür existieren vorgefertigte Klassen und Module, die man einfach benutzen kann... und es funzt. Man braucht dafür nicht mal wirklich Kenntnisse über den Verbindungsaufbau, Datentransfer und Verbindungsabbau beim FTP zu haben.

    Wenn man jedoch einen FTP-Server selbst programmieren will, ist das jedoch etwas anderes.

    Wichtiges im Voraus, bevor ihr weiterlest:
    Bitte keine Vorschläge machen, dass ich ein fertiges Freeware-Programm irgendwo runterladen soll. Und bitte nicht sofort hier alles in Frage stellen, nach dem Motto "Warum machst du stattdessen nicht dies, ist doch viel einfacher". Darauf steh ich gar nicht. Habe es mir in den Kopf gesetzt und damit basta.:biggrin:
    Es ist vollkommen egal für welche Anwendung ich das brauche und soll auch nicht Thema dieses Threads sein.
    Ich bin mir den Sicherheitsrisiken bewusst ein eigenes FTP Server Programm zu benutzen. Fragen und Anregungen in diese Richtung sind auch nicht Thema dieses Threads (zumindest erstmal nicht!).


    So jetzt habe ich beschrieben, was dieser Thread nicht sein soll. Nun komme ich zum wichtigen Teil, meiner Frage:

    Wie bewerkstelligt man sowas?

    Die Grundlagen zu FTP sind in dem RFC 959 hinterlegt. Dort findet man u.a. die Architektur des FTP Modells und die Befehle mit denen der Verbindungsaufbau, Datentransfer, Verbindungsabbau, etc. gesteuert werden kann.

    Soweit so gut. Qt liefert zudem leistungsstarke Klassen zur Netzwerk- bzw. Socketprogrammierung.

    Wie würdet ihr an diese Sache herangehen?

    Also ich würde mir erst einmal einige Diagramme zeichnen, wie das mit dem Verbindungsaufbau und -abbau sowie dem Datentransfer funktioniert. Weiterhin noch die Unterschiede zwischen Active und Passive Mode darstellen.
    Dann würde ich 2 Testprogramme schreiben. Eines soll den Server, das andere den Client darstellen. Der Verbindungsauf- und abbau soll testweise durchgeführt werden. Funktioniert das, so kann man auch einen Datentransfer initiieren. Als nächster Schritt würde kommen, dass man die Befehle in dem Serverprogramm implementertiert, die nach dem RFC-Standard vorgegeben sind. Als Clientseitiges Testprogramm ließe sich da nun sowas wie Filezilla nutzen.

    Jetzt kommt aber noch ein Problem dazu: Auf der Serverseite muss ich eine eigene Benutzerverwaltung erstellen, die die erlaubten Nutzer, deren Passwörter sowie deren Zugriffsrechte auf das Dateisystem des Servers festlegt. Langsam wird's aufwändig, oder?:biggrin:

    Vielleicht kennt der eine oder andere von euch auch eine gute Seite, wo ich weitere Informationen herkriegen könnte. Dies wäre auch schon Gold wert. Ich habe nämlich dazu kaum was anständiges gefunden, wo die Informationen, die ich brauche schön gebündelt auf einer Webseite zu finden sind. Habe aber z.B. das hier gefunden. Ist schon mal auch nicht schlecht, aber ich suche nicht so die Quellcodes, sondern eher eine Art "How To".

    Viele Grüße
    tangoal

    PS: Derjenige, der sich den Text bis hierhin sorgfältig durchgelesen hat, kriegt ein positives Karma von mir. :thumb:
    Kleine Einschränkung: Freiwillige schreiben mir eine PN, ich stelle ihnen eine Frage, die innerhalb einer gesetzten Frist beantwortet werden muss. Ist die Antwort in meinem Sinne gut erklärt und richtig, so wird ein positives Karma vergeben. Ein Blender und Nixwisser kriegt ein negatives Karma.:wink:



  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Auf welchem Betriebssystem soll der Server denn laufen?
    Unter Windows wird die Benutzerverwaltung relativ komplex, weil du wirklich alle Zugriffe überprüfen musst. Bei Linux wäre das ganze einfacher, weil auch andere FTP-Server hierfür die Rechteverwaltung von Linux verwenden.
    Dadurch müsste sich dein Server nicht mehr in dieser Hinsicht um die Sicherheit kümmern und könnte einfach ein "Zugriff verweigert" senden, wenn der Dateizugriff nicht geht.
    Ich weiß ja nicht, inwiefern du dich schon mit Linux beschäftigt hast, aber dort sind die Rechte für das Verzeichnis jedes Benutzers auf 700 gesetzt, also der Besitzer hat Vollzugriff und alle anderen gar keinen.

    Was ich dir noch allgemein empfehlen könnte, wäre erstmal einen ganz einfachen Server zu programmieren, ohne ein solch komplexes Protokoll, falls du das noch nicht gemacht hast.

    LG cookies
  4. Autor dieses Themas

    tangoal

    Kostenloser Webspace von tangoal

    tangoal hat kostenlosen Webspace.

    cookies schrieb: Auf welchem Betriebssystem soll der Server denn laufen?
    Unter Windows wird die Benutzerverwaltung relativ komplex, weil du wirklich alle Zugriffe überprüfen musst. Bei Linux wäre das ganze einfacher, weil auch andere FTP-Server hierfür die Rechteverwaltung von Linux verwenden.
    Dadurch müsste sich dein Server nicht mehr in dieser Hinsicht um die Sicherheit kümmern und könnte einfach ein "Zugriff verweigert" senden, wenn der Dateizugriff nicht geht.
    Ich weiß ja nicht, inwiefern du dich schon mit Linux beschäftigt hast, aber dort sind die Rechte für das Verzeichnis jedes Benutzers auf 700 gesetzt, also der Besitzer hat Vollzugriff und alle anderen gar keinen.

    Möglichst unabhängig vom Betriebssystem. Also wäre eine eigene Benutzer- und Rechteverwaltung selbst zu programmieren. Nach momentanen Stand will ich das Programm aber unter Windows laufen lassen.

    Was ich dir noch allgemein empfehlen könnte, wäre erstmal einen ganz einfachen Server zu programmieren, ohne ein solch komplexes Protokoll, falls du das noch nicht gemacht hast.

    Also bisher habe ich mit MFC mal eine Art Server geschrieben, sollte mit Qt einfacher gehen, denke ich:wink:
    Ist aber der erste Schritt, denn man machen sollte, hast recht. Das meinte ich auch mit den beiden Testprogrammen:
    Eines soll den Server, das andere den Client darstellen. Der Verbindungsauf- und abbau soll testweise durchgeführt werden.

    Da Qt schon Klassen zur Verfügung stellt, die TCP-Verbindungen ermöglichen, ist das nicht so das Problem, denke ich.
  5. Das ist genau das Gegenteil von dem, was du willst, aber:

    Wenn du wirklich mal einen eigenen FTP-Server schreiben willst, um dich mit dem Protokoll vertraut zu machen und auch TCP etwas zu verstehen, würde ich persönlich lieber versuchen solche einen Server mit node.js zu implementieren. Du hast dort TCP zur Verfügung, gleichzeitig aber die "bequemere" Sprache JavaScript und zudem die Geschwindigkeit von node.js voll auf deiner Seite. (Gut, ein nativ in C entwickelter Server ist natürlich noch schneller, aber da musst du dich dann auch wirklich selbst um Kram kümmern wie "Will ich für jede Connection einen neuen Prozess starten?", usw.)

    €dit: PS: node.js ist voll kuhl :D

    Beitrag zuletzt geändert: 1.6.2010 23:22:18 von nikic
  6. Autor dieses Themas

    tangoal

    Kostenloser Webspace von tangoal

    tangoal hat kostenlosen Webspace.

    nikic schrieb: Das ist genau das Gegenteil von dem, was du willst, aber:

    Gegenteil nicht, aber suche eine Lösung in C/C++ wobei ich wohl die Qt-Libs verwenden werde. Für mich persönlich ist die JS-Lösung nicht bequemer, weil ich keinen Plan davon habe. Und ein FTP-Serverprogramm als Einstieg in die JS-Programmierung ist vielleicht nicht so das richtige, da tauchen bestimmt Merkwürdigkeiten auf, die ich nicht so schnell lösen kann, weil ich die Eigenheiten von JS noch nicht so kenne;-)

    Und wie gesagt: Es interessiert mich mehr die Herangehensweise und was ich so zu beachten habe. Wenn ich das so etwas näher beleuchten kann, dann kann ich das in der Programmierung auch durchziehen.

    PS: du hast den Teil mit "Wichtiges im Voraus, bevor ihr weiterlest:" im Startpost wohl übersehen... :biggrin:



    Beitrag zuletzt geändert: 1.6.2010 23:29:56 von tangoal
  7. Erstmal: Ich habe mich noch nie wirklich mit der Programmierung / dem Aufgbau von FTP Programmen auseinander gesetzt. Daher sind meine Antworten hier alle die eines Programmierers, der sich zwar mit Qt, nicht aber wirklich mit dem Protokoll auseinander setzt.
    Im Grunde brauchst du auch nur 1 Programm, bei den Qt Examples ist auch ein fertiges FTP (Client) Programm dabei, d.h. du kannst dich voll auf deinen Server konzentrieren.
    Nun zu dem was ich eigentlich sagen wollte.
    Du solltest du beachten, das es beim FTP Programm & Server 2 verschiedene Modi gibt, den ASCII & den Binärmodus. :) Das habe ich bei meinen PHP Programmierungen bereits bemerkt. :)
    Ansonsten musst du erstmal schauen, wie du das Protokoll inkludieren kannst. :)
  8. everydaynormalguy

    everydaynormalguy hat kostenlosen Webspace.

    Hi,

    Ich würde das so machen:
    QTcpServer, für jede eingehende Verbindung ein QTcpSocket (ne QList<QTcpSocket*> anlegen). Sobald sich ein Client meldet, Passwort und User abfragen (diese in files lokal speichern, beim Programmstart auch in list packen). Gelingt die Authentifizierung kommt wahrsch. ein request mit Pfad und File. Mit QFile->readAll() file einlesen und auf Socket schreiben. Fertig :-)

    Weis leider net wie das FT-Protokol ganau aussieht, aber lässt sich bestimmt rausfinden. Die TCPSockets haben manchma Probs mit der Firewall, evtl ports Freigeben. Und überhaupt: FTP-Server nicht selber machen ;-)

    CesarFTP kann ich Dir für Testzwecke und zur Inspiration zwecks zu implementierender Features empfehlen. Würde Dir aber echt empfehlen,Dich auf Deinen eigentlichen Plan zu konzentrieren und Dich nicht mit der Programmierung eines FTP Servers aufzuhalten.

    MfG, edng
  9. Autor dieses Themas

    tangoal

    Kostenloser Webspace von tangoal

    tangoal hat kostenlosen Webspace.

    robbmaster schrieb: Erstmal: Ich habe mich noch nie wirklich mit der Programmierung / dem Aufgbau von FTP Programmen auseinander gesetzt. Daher sind meine Antworten hier alle die eines Programmierers, der sich zwar mit Qt, nicht aber wirklich mit dem Protokoll auseinander setzt.
    Im Grunde brauchst du auch nur 1 Programm, bei den Qt Examples ist auch ein fertiges FTP (Client) Programm dabei, d.h. du kannst dich voll auf deinen Server konzentrieren.
    Nun zu dem was ich eigentlich sagen wollte.
    Du solltest du beachten, das es beim FTP Programm & Server 2 verschiedene Modi gibt, den ASCII & den Binärmodus. :) Das habe ich bei meinen PHP Programmierungen bereits bemerkt. :)
    Ansonsten musst du erstmal schauen, wie du das Protokoll inkludieren kannst. :)

    Danke für die Anmerkungen, robbi. Helfen mir aber nicht so weiter.
    Einen FTP Client zu schreiben ist null Problemo. Ein Beispiel liefert die Super-Qt-Hilfe mit. Einen FTP-Server zu schreiben ist relativ ungewöhnlich. Ich habe zumindest so einige Webseiten gefunden, die beschreiben, welche Befehle ein FTP-Server unterstützen soll (mit welchen Befehlen ein Client ihn ansprechen kann). Das mit den beiden Modi ist mir schon klar, jedoch muss ich die quasi selber implementieren, mehr oder weniger^^ Man kann kein "Protokoll inkludieren", leider :-)

    Hm, ich versuche mal meine Frage noch etwas genauer zu formulieren, da ich nun konkreter werden kann als noch vor einigen Tagen:

    Habe Probleme bei der Vorstellung, ein Server-Programm zu haben, welches von mehreren Clients auch gleichzeitig angesprochen werden kann und auch gleichzeitig Dateiübertragungen vornehmen kann. Ist das überhaupt möglich? Soll ich für jede Dateiübertragung / Kommunikation einen eigenen Thread machen? Oder wie soll ich die Abläufe in eine klare Struktur bringen?
    Was ich möchte ist, dass ich eine Art Ablaufplan habe, bevor ich mit dem Implementieren anfange. Ideen dafür gibt es bei mir schon, aber kann diese schlecht ausformulieren (weder in Text- noch in Bildform). Von daher suche ich eure Hilfe.
    Es ist kein Qt-spezifisches Problem, sondern ein logisches bzw. architektonisches Problem.

    Werde am Wochenende aber noch einige Ideen austesten. Vielleicht hilft mir das und ich komme einen Schritt weiter.

    Viele Grüße tangoal

    Beitrag zuletzt geändert: 10.6.2010 22:53:26 von tangoal
  10. Hm also von eigenen Prozessen pro Verbindung würde ich abraten.Threads sind da schon was anderes aber ich würde dir einen Threadpool ans Herz legen. Was den Dateizugriff angeht, musst du dir Gedanken darüber machen, wie du mehrfachen Zugriff auf eineDatei regelst. Ich würde eine Datei nur von einer Verbindung auf einmal zugreifbar machen, da es sonst eventuell zu Fehlern kommen kann(diese Problem hättest du ohne mehrere Prozesse/Threads wohl nicht). Ansonsten ist es kein Problem mehrere Clients gleichzeitig mit Daten zu bedienen.
  11. everydaynormalguy

    everydaynormalguy hat kostenlosen Webspace.

    Hi,
    ich hab ma ne P2P Architektur zur Vernetzung mechatronischer Systeme entwickelt (war so ne art SOA 2.0). Die Systeme mussten ihre Interaktion dezentral und im direkten Kontakt miteinander organisieren (um die Latenz zu reduzieren, war ne zeitkritische Angelegenheit, weil Roboter und Menschen nen gemeinsamen Arbeitsraum teilten, son Sicherheitsding, wie auch immer).
    Was für dich interessant sein könnte is die Klasse "CommunicationManager" (CM). Die hatte so in etwa, was Du brauchst (ein Server, der beliebig Clients verwalten kann)

    .h
    #ifndef COMMUNICATIONMANAGER_H
    #define COMMUNICATIONMANAGER_H
    
    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QStringList>
    
    class CommunicationManager : public QObject
    {
        Q_OBJECT
    
    public:
        CommunicationManager(QObject *parent = 0);
    
    public slots:
        void Top2this(const QString &, const QString &);
    
    private slots:
        void newConnection();
        void readSocket();
        void connectionClosed();
    
    signals:
        void this2Top(const QString &,const QString &);
    
    private:
        QTcpServer *Server;
        QList<QTcpSocket*> *SocketList;
        QStringList *IDList;
    };
    
    #endif // COMMUNICATIONMANAGER_H


    .cpp
    #include "communicationmanager.h"
    
    CommunicationManager::CommunicationManager(QObject *parent)
    {
        SocketList = new QList<QTcpSocket*>;
        IDList = new QStringList;
        Server = new QTcpServer;
        connect(Server,SIGNAL(newConnection()),this,SLOT(newConnection()));
    }
    
    void CommunicationManager::Top2this(const QString &ID, const QString &Message)
    {
        QString qs = Message;
        qs.remove(0,6);
        if(qs.startsWith("Send"))
        {
            qs.remove(0,6);
            qs += "\n";
            int index = IDList->indexOf(ID);
            if(index == -1)
            {
                emit this2Top(ID,"GUI::Error: Trying to write to an unconnected Device");
            }
            else
            {
                SocketList->at(index)->write(qs.toLocal8Bit());
            }
        }
    
        else if(qs.startsWith("Initialize"))
        {
            QStringList tokens = ID.split(QRegExp(":"),QString::SkipEmptyParts);
            Server->listen(QHostAddress::Any,tokens[1].toInt());
        }
    
        else if(qs.startsWith("Connect"))
        {
            if(!IDList->contains(ID))
            {
                QTcpSocket *Socket = new QTcpSocket;
                connect(Socket,SIGNAL(readyRead()),this,SLOT(readSocket()));
                connect(Socket,SIGNAL(disconnected()),this,SLOT(connectionClosed()));
                QStringList tokens = ID.split(QRegExp(":"),QString::SkipEmptyParts);
                Socket->connectToHost(QHostAddress(tokens[0]),tokens[1].toInt());
                SocketList->append(Socket);
                IDList->append(ID);
            }
        }
    
        else
        {
            emit this2Top(ID,"GUI::Error: Unknown message: "+Message);
        }
    }
    
    void CommunicationManager::newConnection()
    {
        QTcpSocket *Socket = Server->nextPendingConnection();
        connect(Socket,SIGNAL(disconnected()),this,SLOT(connectionClosed()));
        IDList->append(Socket->peerAddress().toString()+QString(":%1").arg(Socket->peerPort()));
        SocketList->append(Socket);
        emit this2Top(IDList->last(),"GUI::NewDeviceAvailable");
        connect(Socket,SIGNAL(readyRead()),this,SLOT(readSocket()));
    }
    
    void CommunicationManager::readSocket()
    {
        QTcpSocket *Socket = (QTcpSocket*)sender();
        QString qs;
        while (Socket->bytesAvailable())
        {
            qs = Socket->readLine();
            if(qs!="")
            {
                int index = SocketList->indexOf(Socket);
                if(index == -1)
                {
                    emit this2Top("Default","GUI::Error: Unexpected message by unregistered device:"+qs);
                }
                else
                {
                    qs.remove("\r");
                    qs.remove("\n");
                    emit this2Top(IDList->at(index),qs);
                }
            }
        }
    }
    
    void CommunicationManager::connectionClosed()
    {
        QTcpSocket *Socket = (QTcpSocket*)sender();
        int index = SocketList->indexOf(Socket);
        if(index != -1)
        {
            QString qs = IDList->at(index);
            IDList->removeAt(index);
            SocketList->removeAt(index);
            emit this2Top(qs,"GUI::ConnectionClosed");
            emit this2Top(qs,"Sub::ConnectionClosed");
        }
    }


    Musste Dir wahrsch noch ein bisschen anpassen. Würde dann noch nen FileManager schreiben, der liest und schreibt, was über den CM so reinkommt. Hoffe des hilft Dir!
    MfG, edng


  12. tangoal schrieb:
    Habe Probleme bei der Vorstellung, ein Server-Programm zu haben, welches von mehreren Clients auch gleichzeitig angesprochen werden kann und auch gleichzeitig Dateiübertragungen vornehmen kann. Ist das überhaupt möglich? Soll ich für jede Dateiübertragung / Kommunikation einen eigenen Thread machen? Oder wie soll ich die Abläufe in eine klare Struktur bringen?


    (Gut, ein nativ in C entwickelter Server ist natürlich noch schneller, aber da musst du dich dann auch wirklich selbst um Kram kümmern wie "Will ich für jede Connection einen neuen Prozess starten?", usw.)

    Jetz weißt du, warum ich zu node.js geraten habe. Wenn du dir mal Apache, Lighttpd und node.js ansiehst, wirst du sehen, dass es sehr viele verschiedene Ansätze gibt, wie man mehrere Verbindungen gleichzeitig regelt. Die Qual der Wahl :D

    PS: du hast den Teil mit "Wichtiges im Voraus, bevor ihr weiterlest:" im Startpost wohl übersehen... :biggrin:
    Nein, ich hab es nicht überlesen:
    Das ist genau das Gegenteil von dem, was du willst, aber:


    Ich bleibe immernoch bei dem Tipp mit node.js. Damit kannst du dem FTP-Protokoll näher kommen und es implementieren, aber das ganze rumge-C-tere weglasse - sprich dir die 20 Stunden Debugging ersparen ;) (Übrigens, JavaScript musst du auch nicht wirklich lernen, wenn du C kannst. Das ergibt sich von selbst.)
  13. Autor dieses Themas

    tangoal

    Kostenloser Webspace von tangoal

    tangoal hat kostenlosen Webspace.

    nikic schrieb: Ich bleibe immernoch bei dem Tipp mit node.js. Damit kannst du dem FTP-Protokoll näher kommen und es implementieren, aber das ganze rumge-C-tere weglasse - sprich dir die 20 Stunden Debugging ersparen ;) (Übrigens, JavaScript musst du auch nicht wirklich lernen, wenn du C kannst. Das ergibt sich von selbst.)

    Du hast womöglich Recht das dies einfacher ist und das JavaScript vom Programmieren her nicht schwer ist, wenn man schon etwas C und Java kann. Ich bin aber vorsichtig bei Systemen, die mir schon "zuviel Arbeit abnehmen". Ich bin noch in der Lernphase, in der ich aber auch etwas tiefer in Materien eindringen möchte. Gerade solche nebenläufige Prozesse, Threads und deren Kommunikation und Synchronisierung finde ich sehr spannend und fange deshalb an mich da reinzufuchsen.
    Dein Vorschlag ist gut gemeint und auch gut. Die Technologie werde ich irgendwann benötigen. Von daher danke, dass du sie mir bekannt machst^^
    Jetz weißt du, warum ich zu node.js geraten habe. Wenn du dir mal Apache, Lighttpd und node.js ansiehst, wirst du sehen, dass es sehr viele verschiedene Ansätze gibt, wie man mehrere Verbindungen gleichzeitig regelt. Die Qual der Wahl :D

    Ja, ich will aber nicht jedes Problem "umgehen". Auch wenn ich zugeben muss, es klingt auf dem ersten Blick dämlich einen FTP-Server programmieren zu wollen. Aber wie gesagt, mich interessiert die Logik und Funktionsweise dahinter. Ok, Qt nimmt einem auch schon eine Menge Arbeit ab, aber noch auf einer tieferen Ebene... :-)

    everydaynormalguy schrieb: Musste Dir wahrsch noch ein bisschen anpassen. Würde dann noch nen FileManager schreiben, der liest und schreibt, was über den CM so reinkommt. Hoffe des hilft Dir!

    Danke, das ist doch schon mal ein Ansatz:-)
  14. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!