C#: Bilddatei / Worddatei über Netzwerk übertragen
-
Weil ich nun schon seit 2 Stunden via google suche, und nur Codes gefunden habe, welche überhaupt nicht funktionieren, poste ich hier einmal meine Frage:
Wie kann ich mit C# eine beliebige Datei (hauptsächlich .jpeg und .doc) über das Netzwerk senden?
Den Server / Client aufbau mit TcpListener und TcpClient habe ich natürlich schon.
Vielen Dank!
-
File.Copy(path, path2)
-
...
Ja weil File.Copy() natürlich ein C# Befehl ist, der eine Datei übers Netzwerk kopiert...
-
Client <====> Server
Client sendet Server eine Datei,
Server nimmt die Datei an,
Server speichert die Datei.Das wäre der Plan..
-
Wenn Du mit TcpListener/TcpClient schon arbeitest - Wo harkts denn?
-
filesender schrieb:
...
Ja weil File.Copy() natürlich ein C# Befehl ist, der eine Datei übers Netzwerk kopiert...String source = "\\\\rechner1\\pfad\\datei.endung"; String destination = "\\\\rechner2\\pfad\\datei.endung"; IO.File.Copy(source, destination);
wieso sollte das nicht gehen?
-
@mogel, weil du anscheinend meinen Post nicht liest...
Ich habe einen Client und einen Server, beide in C# gecoded.
Der Client soll dem Server eine Datei schicken, diese nimmt sie an und speichert sie wo ab.Es geht nicht daraum auf einem gemounteten Netzwerkpfad eine Datei zu kopieren.
LG
-
@geeky
mein ansatz war:client: lies das file komplett in einen string ein. (streamreader etc)
dann sende den string über die netzwerkverbindung (streamwriter auf networkstream)der server nimmt die datei an und speichert sie ab.
natürlich gibts erst noch ein austausch so in art:
client: hello filetransfer
server: filetransfer ok
client: accept file.doc
server: file.doc ok
----> sending ---> ...Problem:
Die Datei "kommt nicht richtig an", sprich es muss etwas fehlen, der letzte Teil meiner Meinung..exe können nicht mehr ausgeführt werden (keine win32 anwendung), .jpg bilder werden nicht mehr erkannt, docs haben fehler etc.
hab mir mal ein .jpeg bild unter linux angesehen, und der letzte teil des bildes ist schwarz, sprich der letzte dateiteil scheint zu fehlen.
LG
-
filesender schrieb:
@mogel, weil du anscheinend meinen Post nicht liest...
doch habe ich gemacht ... aber ... Du hast behauptet damit kann man keine Datei über das Netzwerk kopiert ... es geht aber
filesender schrieb:
Es geht nicht daraum auf einem gemounteten Netzwerkpfad eine Datei zu kopieren.
Du schreibst aber erst jetzt genauer was Du bisher gemacht hast
filesender schrieb:
client: lies das file komplett in einen string ein. (streamreader etc)
ich habe keine Ahnung wer im Internet den Bullshit verbreitet das man Datien in einen String einlesen und bearbeiten kann ... ich verstehe nicht was daran so verwerflich ist das einfach in ein Byte-Array zu halten so wie es auf der Pladde "steht"
filesender schrieb:
Die Datei "kommt nicht richtig an", sprich es muss etwas fehlen,
Du pumpst bestimmt gleich die Datei in das Netzwerk ohne vorher der anderen Seite die Länge mitzuteilen ... um aus einem Wasserhahn 1 Liter abzumessen nimmst Du sicher auch einen Messbecher und keine einfache Schüssel?
filesender schrieb:
der letzte Teil meiner Meinung.
das kannst Du doch sicher überprüfen
hand, mogel
-
1. Ich muss Mogel Recht geben Netzwerk ist nicht immer gleich Internet...
2. Mit dem Byte Array hat er auch Recht, alles andere ist blödsinn...
3. Du musst das Array am Ende terminieren falls du vorher schon eine Buffergröße hast, also alle leeren Felder weglassen
4. Ich habe mal gelesen dass bei exe Dateien noch 1 oder 2 leere bytes zum Schluss hinzugefügt werden müssen, keine Ahnung ob das stimmt
-
Wichtig ist eigentlich nur, daß die Dateien im Binärmodus eingelesen werden und dann in ein byte-Array gepackt werden...
und auf Empfänger-Seite entsprechend wieder binär geschrieben werden.
-
Ich würde es mit einem Webservice machen.
-
[quote="mogel"]
filesender schrieb:
@mogel, weil du anscheinend meinen Post nicht liest...
doch habe ich gemacht ... aber ... Du hast behauptet damit kann man keine Datei über das Netzwerk kopiert ... es geht aber
Mein Fehler. Das "geht nicht" war natürlich auf meine Problemstellung bezogen
filesender schrieb:
Es geht nicht daraum auf einem gemounteten Netzwerkpfad eine Datei zu kopieren.
Du schreibst aber erst jetzt genauer was Du bisher gemacht hast
Nope...
Mein Post:
Client <====> Server
Client sendet Server eine Datei,
Server nimmt die Datei an,
Server speichert die Datei.Das wäre der Plan..
Sollte eigentlich klar sein...
filesender schrieb:
client: lies das file komplett in einen string ein. (streamreader etc)
ich habe keine Ahnung wer im Internet den Bullshit verbreitet das man Datien in einen String einlesen und bearbeiten kann ... ich verstehe nicht was daran so verwerflich ist das einfach in ein Byte-Array zu halten so wie es auf der Pladde "steht"
Habs jetzt mit einem Byte Array probiert. Selbes Problem
filesender schrieb:
Die Datei "kommt nicht richtig an", sprich es muss etwas fehlen,
Du pumpst bestimmt gleich die Datei in das Netzwerk ohne vorher der anderen Seite die Länge mitzuteilen ... um aus einem Wasserhahn 1 Liter abzumessen nimmst Du sicher auch einen Messbecher und keine einfache Schüssel?
Finde ich jetzt interessant.
Ich fahre ja eig über TCP, was bedeutet, dass das Ding solange gesendet wird bis alles angekommen ist. Mein Reader liest einfach so lange, bis nichts mehr ankommt, und schreibt das dann in eine Datei.Kannst du mir kurz erklären, warum ich ihm die Länge mitteilen muss? Ich mein er liest ja alles aus, sonst würde er das Ding nicht in eine Datei schreiben. (while daten ankommen => lesen)
filesender schrieb:
der letzte Teil meiner Meinung.
das kannst Du doch sicher überprüfen
Wie gesagt, es ist der letzte Teil, siehe oben bezüglich dem Bild unter Linux.
-
filesender schrieb:
Mein Post:
Client <====> Server
Client sendet Server eine Datei,
Server nimmt die Datei an,
Server speichert die Datei.Das wäre der Plan..
Sollte eigentlich klar sein...
natürlich ... das ist das Prinzip wie Daten über das Netzwerk ausgetauscht wird ... so mache ich das auch ... aber es fehlten Details und bei denen hapert es ja
- wie wir nun wissenHabs jetzt mit einem Byte Array probiert. Selbes Problem
weil Dein problem nicht das Einlesen sondern das Übertragen deer Daten ist ... theoretisch funktioniert es unter .NET das ganze in einen String zu packen ... bei anderen Sprachen (vgl. C oder C++[?]) wird es definitiv nicht funktionieren .. .da kann Dir durchaus das programm die Hufe hochreisen
Ich fahre ja eig über TCP, was bedeutet, dass das Ding solange gesendet wird bis alles angekommen ist. Mein Reader liest einfach so lange, bis nichts mehr ankommt, und schreibt das dann in eine Datei.
Kannst du mir kurz erklären, warum ich ihm die Länge mitteilen muss? Ich mein er liest ja alles aus, sonst würde er das Ding nicht in eine Datei schreiben. (while daten ankommen => lesen)
wie wäre es mit Timeout ... lass mal das Netzwerk etwas hängen ... da kommen ja keine Daten mehr an - aber die Datei ist nicht vollständig ... ansonsten schau Dir mal andere Protokolle an ... das ist fast immer eine Länge der Daten mit drinnen ... wenn nicht, dann wird das Ende entsprechend anders Definiert
oder anders ausgedrückt ein Stream ist ein Wasserhahn ... irgendwie muss Dein Wasserversorger auch messen was Du verbraucht hast ... ein "der braucht jetzt kein Wasser mehr" ist keine Mengeangabe
hand, mogel
-
Vielen dank für den Hinweis,
Hast du mir einen kurzen Pseudocode um das zu verdeutlichen?
-
Mit der Überlegung, dass es in C# auch mit Strings klappt, habe ich folgende zwei methoden der klasse netzwerk erstellt:
server_file_protokoll
public static bool server_file_protocol(NetworkStream ns) { string temp = ""; string filesize = ""; string filename = ""; string file = ""; try { StreamWriter sw = new StreamWriter(ns); StreamReader sr = new StreamReader(ns); temp = sr.ReadLine(); if (!temp.Contains("EHLO FILE")) return false; sw.WriteLine("ACCEPT FILE"); sw.Flush(); temp = sr.ReadLine(); if (!temp.Contains("SIZE FILE:")) return false; string[] split = temp.Split(':'); //split[1] hat nun den wert von filesize weil: SIZE FILE: 2000 z.B. filesize = split[1]; sw.WriteLine("ACCEPT FILESIZE: " + filesize); sw.Flush(); temp = sr.ReadLine(); if (!temp.Contains("NAME FILE:")) return false; split = temp.Split(':'); //split[1] hat nun den wert vom dateinamen filename = split[1]; sw.WriteLine("ACCEPT FILENAME: " + filename); sw.Flush(); while (!(temp = sr.ReadLine()).Contains("END FILE")) { if (!temp.Contains("END FILE")) file += temp + "\n"; } sw.WriteLine("END FILE"); sw.Flush(); try { StreamWriter sa = new StreamWriter(filename); sa.Write(file); sa.Close(); } catch { return false; // could not be saved! } } catch { return false; } return true; }
client_file_protokol
public static bool client_file_protocol(NetworkStream ns, string path) { string tmp = ""; string file = ""; try { StreamWriter sw = new StreamWriter(ns); StreamReader sr = new StreamReader(ns); sw.WriteLine("EHLO FILE\n"); sw.Flush(); tmp = sr.ReadLine(); if (!tmp.Contains("ACCEPT FILE")) return false; sw.WriteLine("SIZE FILE: " + logic.count_file(path) + "\n"); sw.Flush(); tmp = sr.ReadLine(); if (!tmp.Contains("ACCEPT FILESIZE")) return false; sw.WriteLine("NAME FILE: " + logic.strip_path(path) + "\n"); sw.Flush(); tmp = sr.ReadLine(); if (!tmp.Contains("ACCEPT FILENAME")) return false; StreamReader read = new StreamReader(path); while ((tmp = read.ReadLine()) != null) { file += tmp; } read.Close(); // send the file to the server sw.WriteLine(file); sw.Flush(); // tell server that's the file end! sw.WriteLine("END FILE\n"); sw.Flush(); tmp = sr.ReadLine(); if (!tmp.Contains("END FILE")) return false; } catch { return false; } return true; }
Wenn ich eine .txt Datei übertragen will, klappts 1A.
Bei ner .jpeg Datei, haut das Ganze nicht mehr hin.
Irgendwie ist die übertragene .jpeg Datei Größer als das Original und kein "valid .jpeg file"Bitte um Unterstützung.
-
Wenn ich eine .txt Datei übertragen will, klappts 1A.
Bei ner .jpeg Datei, haut das Ganze nicht mehr hin.weil Du nicht hören willst
filesender schrieb:
Mit der Überlegung, dass es in C# auch mit Strings klappt
nun brauchst Du Dich auch nicht zu wundern wieso da nix übertragen wird, weil String dafür ungeeignet ist -> Byte Array (himmelherrgottgrüzi%§&%§)"§!!)
--
machen wir das Ganze mal anders
Frage: wieso kann man unter C keine Bilder in einen String speichern?
Antwort: In einem Bild kommt mit hoher Wahrnscheinlichkeit ein 0x00 vor - teilweise sogar mehrere ... unter C wird aber ein Stringende mittels 0x00 gekennzeichnet ... somit hört der String sofort auf und strlen() liefert die falsche Länge
Frage: Wieso funktioniert das aber unter .NET?
Antwort: Unter .NET kann man Unicode-Zeichenketten in der Stringklasse speichern ... da aber hier auch durch die Kodierung ein 0x00 vorkommen kann, muss die Länge in einem extra Member gespeichert werden ... somit ist immer die korrekte Länge der Zeichenkette bekannt ... lesen kann das Bild aber dennoch keiner - ist aber auch egal
Frage: Wieso kann ich mit meinem Code eine Textdatei übertragen aber kein JPEG-Bild (oder andere Binärdatei [Anmerkung des Autors])?
Antwort: Weil in einer Textdatei 0x0A bzw. 0x0D für ein Zeilenende verwendet werden ... die werden aber durch ReadLine() entsprechend rausgefiltert ... durch das speichern in eine Datei werden diese aber wieder indirekt eingefügt ... daher sieht es so aus als wenn die Datei korrekt übertragen wurde ... eigentlich auch nicht - aber es funktioniert
Frage: und JPEG-Bild??
Antwort: da darfst Du nun mal alleine Nachdenken ... wenn Du die Lösung gefunden wirst Du definitiv mit diesem Binär-Zeichenketten-Blödsinn aufhören und es endlich richtig machen
--
im Übrigen schickst Du zwar die Länge mit - überprüfst aber nicht zum Schluß ... außerdem sehe ich gerade das Du das Zeilenende von Hand in die Zeichenkette einfügst (
)
-
Ich habe jetzt gerade in der MSDN-Doku gelesen:
StreamReader::ReadLine Method:
A line is defined as a sequence of characters followed by a line feed ("\n"), a carriage return ("\r") or a carriage return immediately followed by a line feed ("\r\n"). The string that is returned does not contain the terminating carriage return or line feed.Sieht so aus das dein Client die 0x0a, 0x0c-Bytes abschneidet was natürlich das Image zerstört. Du solltest dafür etwas binärsicheres verwenden. Du kannst auch im Hexeditor mal schauen was sich verändert hat (z.B. 0x0a => 0x0c0a)
-
filesender schrieb:
Mit der Überlegung, dass es in C# auch mit Strings klappt, habe ich folgende zwei methoden der klasse netzwerk erstellt:
Binärdaten als String übertragen ist keine wirklich gute Idee.
-
Das einzig sinnvolle ist byte für byte übertragen... und wie auch schon angemerkt vorher die größe weil ein leeres byte nicht gleich das ende bedeutet