# FTP-Verbindung per Programm



## Unicate (30. April 2005)

Hallo Welt!

Ich habe ein Problem.
Ich möchte eine Datei aus dem Web auslesen lassen, allerdings habe ich noch keine kluge Idee, wie ich das anstellen soll.

Ich will im Prinzip eine Datenbank ins Netz stellen, auf die ich nur mit meinem Programm zugreifen kann.

Wie stell ich die Verbindung zu dem FTP bzw. zu der Datei her?

Danke für jede Antwort


----------



## Tobias K. (30. April 2005)

moin


Da du weder angaben zum Compiler noch zur Sprache gemacht hast bekommste du einfach mal ein Beispiel das die MFC benutzt:

```
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);

	CInternetSession session;
	CFtpConnection *connection;
	CInternetFile *file;

	char buffer[100];
	

	connection = session.GetFtpConnection("umbrasaxum.um.funpic.de", "umbrasaxum", "thegeilomat", 21, 0);
	if(connection)
		cout<< "Verbunden\n";

	if(connection->SetCurrentDirectory("test"))
		cout<<"Verzeichnis gewechselt\n";
	
	file = connection->OpenFile("xxx.txt", GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 1);

	if(file)
		cout<<"Datei geoeffnet\n";

	file->Read(buffer, 100);

	cout<< buffer;
	session.Close();

	cin.get();
	return 0;
}
```

Ansonsten bemüh mal die Suchfunktion.


mfg
umbrasaxum


----------



## Unicate (30. April 2005)

Danke erstmal!

Habe Windows XP, MSVS v6 

Kannst du deinen Code mal Dokumentieren bitte?
Das sieht so aus als ob ich die MFC's verwenden muss...


welche Libary's muss ich dafür einbinden?
Wenn geht hätt ich das gern für die Konsole (Win32)


----------



## Tobias K. (30. April 2005)

moin


In der MSDN findet man ein Tutorial dazu.
Und ja das Beispiel benutzt die MFC allerdings in der Konsole!


mfg
umbrasaxum


----------



## Unicate (30. April 2005)

Wie binde ich die MFC's in der Konsole mit ein? (noch nie davon gehört...  )

MSDN habsch nix gefunden


----------



## Tobias K. (30. April 2005)

moin


Ich kann das gleich nochmal raussuchen.

Ich hab mir die MFC automatisch einbinden lassen.
Dazu gekommen sind dann

```
#include <tchar.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#endif

#include <afx.h>
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT


// TODO: reference additional headers your program requires here
#include <afxinet.h>
```

Und innerhalb main wird:

```
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
```
aufgerufen.


mfg
umbrasaxum


----------



## Unicate (1. Mai 2005)

Wie kann ich mir dir MFC's automatisch einbinden lassen? 
Bei der erstellung des Arbeitsbereiches?
Im nachhinein?


----------



## Tobias K. (1. Mai 2005)

moin


Bei Studio .Net kannst das angeben wenn du ein neues Konsolenprojekt erstellst.
Da kannst leeres Projekt erstellen ankreuzen und auch MFC verwenden.


mfg
umbrasaxum


----------



## Unicate (2. Mai 2005)

und bei VS 6?


----------



## Tobias K. (2. Mai 2005)

moin


Da dann von Hand die oben erwähnten Header einfügen und den Befehl, vielleicht klappt es ja.


mfg
umbrasaxum


----------



## Unicate (2. Mai 2005)

Ok, das mit der Verbindung funktioniert ganz gut, allerdings disconnected der nicht richtig!
Weil wenn ich nach beenden des Programms auf den FTP will, sagt der mir das da noch jemand drauf ist...

Passiert auch nur, wenn das Programm die Datei nicht findet!

So nach 2 minuten geht es dann erst wieder (ist so ein kostenloser arcor-ftp zum testen)


Noch 2 Fragen:
1: Kannst du mir das:

```
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
```
 mal genauer erklären?

2: Wie hast du die Bibliotheken im nachhinein eingebunden?
Denn mir den voreingestellten, funktioniert das nicht!
Ich musste deine Bibliotheken zu den anderen hinzufügen und dann gings...

Danke aber erstmal

Tip für alle mit dem selben Problem:
MFC's einbinden geht auch bei der erstellung einer Win32 Anwendung


----------



## Tobias K. (2. Mai 2005)

moin


Wenn man jetzt von meinem Beispiel ausgeht, sollte man vielleicht noch ein connection->Close();
machen.


mfg
umbrasaxum


----------



## Unicate (2. Mai 2005)

Also ich habe den Code mal ein wenig geändert und Dokumentiert


```
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);

	CInternetSession session;
	CFtpConnection *connection;
	CInternetFile *file;

	char buffer[100], server[100] = {"home.arcor.de"},login[50] = {"usr"}, passwd[30] = {"pwd"};
	int port = 21;
	
	cout << "Verbinde mit " << server << " ...\n";
	
	if(connection = session.GetFtpConnection(server, login, passwd, port, 0)) // Verbindung herstellen
	{
		cout<< "...mit Erfolg\n";

		cout << "Versuche Verzeichniss zu wechseln...\n";

		if(connection->SetCurrentDirectory("test"))								//Verzeichniss wechseln
		{
			cout<<"...mit Erfolg!\n";
		}	else	{
			cout << "...ohne Erfolg\nVerbindung wird geschlossen!\n";
			connection->Close();
		}
		cout << "Oeffne Datei...\n";

		if(!(file = connection->OpenFile("info.txt", GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 1))) // Datei oeffnen
		{
			cout<<"...ohne Erfolg\nVerbindung wird geschlossen!\n";
			connection->Close();
		}	else	{
			cout<<"mit Erfolg!\n";
		}

		file->Read(buffer, 100);		//Datei lesen

		cout<< buffer;					//Datei ausgeben
		session.Close();
		connection->Close();
	}	else	{
		cout << "Es konnte keine Verbindung hergestellt werden!";
	}
	return 0;
}
```


----------



## Unicate (3. Mai 2005)

Man sieh sich das Bild mal an...

Wie kommt es, dass er da so viel Schmarn aus gibt?


----------



## Matthias Reitinger (3. Mai 2005)

Wahrscheinlich setzt die Methode Read von CInternetFile kein Nullbyte an das Ende der Zeichenkette. Bei der Ausgabe wird deshalb über die eigentliche Zeichenkette hinaus gelesen.

Entweder du löst das dadurch, dass du vorher buffer mit lauter Nullen füllst oder du setzt an das Ende des Strings selber ein 0. Die Länge des Strings wird von Read zurückgegeben.


----------



## Unicate (3. Mai 2005)

Das mit der '\0' hab ich mir auch fast gedacht, allerdings hab ich nicht gewusst wie ich die länge hole, aber wenn Read die länge zurückgibt, wie kann ich das dann in die Funktion selbst einbauen?

```
flie->Read(buffer, ?)
```
Danke


----------



## Tobias K. (3. Mai 2005)

moin


Vielleicht eignet sich GetFile dort besser als Read.


mfg
umbrasaxum


----------



## Unicate (3. Mai 2005)

Hab keine Ahnung von den Funktionen!

Aber ich denke bei Getfile, lädt er die Datei runter... das soll er eigentlich nicht machen.

Gibt es nicht auch hier eine feof funktion?

Dann würde ich das nämlich zeichen für Zeichen auslesen bis feof erreicht ist


----------



## Tobias K. (3. Mai 2005)

moin




> Aber ich denke bei Getfile, lädt er die Datei runter



Nein, GetFile lädt eine Datei in eine Variable.

Guck mal selbst in die MSDN http://msdn.microsoft.com und klick dich da durch.
Es gibt bestimmt auch ne Funktion über die du die Grölße einer Datei ermitteln kannst, aber ich würde mal GetFile versuchen.


mfg
umbrasaxum


----------



## Tobias K. (3. Mai 2005)

moin



```
int i = file->GetLength();
file->Read(buffer, 100);
buffer[i] = '\0';
```

Frag mich ncihtr warum aber GetLength muss vor Read aufgerufen werden, dann funktioniert es wie es soll.


mfg
umbrasaxum


----------



## Unicate (3. Mai 2005)

Sorry, hätt ich auch selber drauf kommen können.

Entschuldige. Werde Lösung angeben, wenn ich eine brauchbare gefunden habe!


----------



## Tobias K. (3. Mai 2005)

moin


!?
Reicht die Lösung nciht die ich eben gepostet hab?


mfg
umbrasaxum


----------



## Matthias Reitinger (3. Mai 2005)

umbrasaxum hat gesagt.:
			
		

> ```
> int i = file->GetLength();
> file->Read(buffer, 100);
> buffer[i] = '\0';
> ```


Wie schon gesagt, Read gibt auch die Anzahl der gelesenen Zeichen zurück. Folgendes würde also auch reichen:

```
int i = file->Read(buffer, 100);
buffer[i] = '\0';
```


----------



## Unicate (3. Mai 2005)

@umbrasaxum: War nicht bös gemeint, ich meine nur dass ich auf die Idee mit der MSDN selber hätte kommen sollen

Ok ich habe mal getestet, den puffer ziemlich groß zu machen, und dann gings (auch ohne '\0')

Jetzt bin ich zwar glücklich das das funktioniert aber ich weiß nicht warum...


----------



## Tobias K. (3. Mai 2005)

moin


Hab ich auch nciht böse aufgefasst.
Hatte eher vermutet das du die Antwort überlesen hattest, da grad ne neue Seite begann.

Es gibt übrigens noch ne ganze Reihe Funktionen mit denen man vorab Informationen über eine Datei bekommen kann.


mfg
umbrasaxum


----------

