C# Bibliothek zur Dateiübertragung

Genesis Rei

Grünschnabel
Hallo Leute,
das ist wohl mein erster Post hier im Forum obwohl ich schon bisschen länger hier registriert bin... :D

Ich hätte da ein Problem und dachte ich wende mich mal an euch, vielleicht könnt ihr mir weiterhelfen :)

Also es ist so... ich schreibe momentan an einer DLL zur Dateiübertragung (in C#). Das ganze funktioniert über TcpClient und TcpListener und den NetworkStream!
Ich kann auch schon Dateien hin und her schicken, kann den Transfer pausieren/fortsetzen (in dem ich einfach die Threads anhalte ;) ) jedoch was mir halt fehlt zu meinem endgültigen Glück... währe z.B. dass ich den Transfer "abbrechen" kann!

Ich habe derzeit absolut keine Idee wie ich eine Funktion zum Abbrechen des Transfers schreiben könnte. Es soll ja nicht die ganze Verbindung gleich flöten gehen oder die Threads abgebrochen werden (wobei auf der Sender-Seite wäre es absolut kein Problem), sondern lediglich den Transfer abgebrochen um z.B. danach ne andere Datei zu verschicken.

Hoffe ihr könnt mir da helfen oder habt wenigstens ein paar Ideen :)

PS: der Transfer sollte aber so abgebrochen werden, dass auch keine Bytes mehr im Stream bleiben sonst gibt das Probleme sobald ich eine andere Datei senden will.
 
V

VScan

Hey,

halllo und herzlich willkommen bei den "Schreibenden" :)

Gibt es etwas Kode, damit man entsprechende Tipps geben kann?

Wie sieht denn der Teil aus, an dem Du die Daten versendest, bzw. empfängst?


VG VScan
 

Genesis Rei

Grünschnabel
Also hier wird die Datei "versendet":

PHP:
//speichert die Größe des Pakets in ein Array
byte[] pufferSize = BitConverter.GetBytes(sendPuffer.Length);

//versendet die Größe des Pakets
nStream.Write(pufferSize, 0, pufferSize.Length);

int sentBytes = 0;
int bytesToSend = 1024;

do {
	if ((sendPuffer.Length - sentBytes) < bytesToSend)
		bytesToSend = (sendPuffer.Length - sentBytes);

		nStream.Write(sendPuffer, sentBytes, bytesToSend);
		sentBytes += bytesToSend;

		mre.WaitOne();
} while (sentBytes < sendPuffer.Length);


Das ist dann noch die stelle wo die Datei "empfangen" wird:

PHP:
int receivedBytes = 0; //Anzahl der empfangenen Bytes
int byteToReceive = 1024; //1 Kilobyte der empfangen werden soll

receivedBytes = nStream.Read(pufferSize, 0, pufferSize.Length);
receivePuffer = new byte[BitConverter.ToInt32(pufferSize, 0)];

//falls die Verbindung getrennt wurde und keine Bytes mehr empfangen werden
//bedeutet es besteht keine Verbindung mehr und alles kann geschlossen werden.
if (receivedBytes == 0) {
	this.Disconnect();
	break;
}

receivedBytes = 0;

do {
	if ((receivePuffer.Length - receivedBytes) < byteToReceive)
		byteToReceive = receivePuffer.Length - receivedBytes;
							
	receivedBytes += nStream.Read(receivePuffer, receivedBytes, byteToReceive);

	mre.WaitOne();
} while (receivedBytes < receivePuffer.Length);

Beide Funktionen werden jeweils in einem eigenen Thread ausgeführt übrigens. Die Funktion zum empfangen der Datei ist dauerhaft am laufen solange die Verbindung besteht, aber die Funktion bzw. der Thread mit der Funktion zum versendet der Datei wird jedes mal aufs neue gestartet sobald der Benutzer eine Datei senden will :)
 
V

VScan

Hallo,

ich habe mir den "Receiver" genauer angesehen, dafür solltest Du dann ein Protokoll implementieren, sonst wird es schwierig, wenn der Socket immer offen ist und es dann natürlich sein kann, dass keine Daten verfügbar sind, obwohl der User noch versucht Daten zu senden und sich der "Receiver" dann "tot wartet".

1. SocketTimeout implementieren. (für unvorhergesehene Wartezeiten, falls der "Sender" eine schlechte Verbindung hat.)
2. Protokoll implementieren. (Erklärung folgt)

ProtocolHeader:
status (2 byte)
dataLength (4 byte)

ProtocolBody:
data (dynamic length)

Somit kannst Du bei jedem Paket, dass du an den "Receiver" sendest, überprüfen, ob der User den Vorgang abgebrochen hat.
Ist prinzipiell nichts anderes als ein IP-Paket.

Was Anderes fällt mir grad nicht ein, ausser ganz grob die Verbindung einfach beenden und neu aufbauen, aber sauber ist das nicht.


Bei dem Sender ist das ganz einfach:
If-Abfrage über ein Status-Flag, das nach jedem Versand eines Pakets prüft, ob der User abgebrochen hat.
Das Flag kannst Du über einen Button setzen, je nach belieben, anschließend wird ein entsprechendes Paket zum "Receiver" gesendet, der anhand des Status feststellt, dass dieser Vorgang abgebrochen wird.


Viele Grüße, ...


Edit: Protokoll ist eventuell der falsche Ausdruck, stattdessen trifft es Paket besser, ... mfg
 
Zuletzt bearbeitet von einem Moderator:

Genesis Rei

Grünschnabel
So ein Packet habe ich mir bereits gebastlelt, aber wird da kein Status mitgeteilt.

Außerdem würde ich das wirklich mit dem Status im Paket machen, dann könnte ichs ja nur auf der Sender-Seite abbrechen.

Theoretisch könnte ich zwar genauso eine Abfrage auch auf der Receiver-Seite machen, aber da könnte ich dann dem Sender nicht mitteilen, dass er aufhören soll Bytes zu schicken!

Also es geht halt nicht wirklich auf. Ich könnte höchstens mehrere Connections einrichten, sprich z.b. für das Senden eine eigene und für das Empfangen eine eigene.
Aber ob das wirklich saubere Programmierung wäre... ?

In einem anderen Forum hab ich den Tipp bekommen, mich mit FTP Steuerung bisschen zu befassen, weil ich mein Problem evtl. auf ähnliche Art lösen könnte, aber bisher hab ich keine gescheihten Tutorials oder Bibliothek gefunden die wirklich tiefer in diese Materie greifen.

Die benutzen auch alle nur iwelche .Net Klassen die ich in diesem Fall aber nicht verwenden kann :(
 
V

VScan

Hey,

das stimmt wohl, somit ist es unumgänglich eine 2. oder sogar 3. Verbindung zu öffnen, um auf beiden Seiten zu erkennen, ob eventuell abgebrochen werden muss.

Jedoch kannst Du auch nach jedem empfangenen Paket ein Bestätigungspaket zurück schicken, und erst nach der erfolgreichen Verifizierung, weitere Daten senden, somit kannst Du auf beiden Seiten prüfen, ob abgebrochen werden soll.

Bei .Net FtpWebRequest/FtpWebResponse kenn ich mich leider nicht so gut aus, allerdings weis ich, dass diese auch 2 Verbindungen nutzen, für Kommando- und Datenübertragung.

Viele Grüße, ...
 
Zuletzt bearbeitet von einem Moderator:

Genesis Rei

Grünschnabel
Vielen Dank für die Infos. Bin schon ein Stückchen weiter mit der Bibliothek (in letzter Zeit sehr wenig Zeit gehabt :( ).

Aber ich denke ich könnts jetzt schaffen :)

Danke nochmals.
 

Neue Beiträge