Entwickler-Ecke
IO, XML und Registry - FileSharing - Problem mit FileStream
Red2Devil - So 02.05.10 16:41
Titel: FileSharing - Problem mit FileStream
Hallo,
ich habe es mir zur Aufgabe gemacht, eine Applikation zu schreiben, die im Netzwerk zu einem Rechner Datein in unterschiedlichster Größe schicken kann. D.h. auch Dateien in der Größenordnung von 2GB oder mehr.
Die Client-Seite:
1) Client schickt Anfrage
2) Client schickt Dateinamen, der verschickt werden soll
3) Client bekommt Bestätigung vom Server
4) Client schickt die Datei los
(Problem!!!!)
Die Server-Seite:
1) Server erwidert Anfrage
2) Server bekommt Dateinamen und sucht Speicherort aus
3) Server schickt Bestätigung
4) Server erhält datei
(Problem!!!!)
damit das ewas klarer wird, stelle ich den CodeAbschnitt mal rein:
Client:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| byte[] filenameByte = Encoding.UTF8.GetBytes(filename); server.Send(filenameByte); byte[] operationByte = new byte[2]; server.Receive(operationByte); int operation = BitConverter.ToInt16(operationByte, 0); Console.WriteLine("Received operation: --{0}--", operation.ToString()); if (operation == 1) { Console.WriteLine("Operation succeeded: {0}\r\nFilePath: {1}", operation.ToString(), onlypath + filename); FileStream fs = new FileStream(onlypath + filename, FileMode.Open); byte[] fileSendByte = new byte[length]; while (fs.Read(fileSendByte, 0, length) == 0) { Console.WriteLine("Send: {0}", Convert.ToString(fileSendByte.Length)); server.Send(fileSendByte); } fs.Close(); server.Close(); } else if (operation == 0) { Console.WriteLine(operation + "\r\n"); server.Close(); } |
Server:
C#-Quelltext
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:
| byte[] filenameByte = new byte[1024]; clientSocket.Receive(filenameByte); string filename = Encoding.ASCII.GetString(filenameByte); Console.WriteLine("---" + filename + "---"); string filepath = Model.LFS.saveFile(filename); if (filepath != "") { filepath.Replace('\\', '/'); Console.WriteLine(filepath); byte[] operationByte = BitConverter.GetBytes(1); clientSocket.Send(operationByte); byte[] fileReceiveByte = new byte[length]; FileStream fs = new FileStream(filepath, FileMode.Append, FileAccess.ReadWrite); while (true) { clientSocket.Receive(fileReceiveByte); Console.WriteLine("Receive: {0}", Convert.ToString(fileReceiveByte.Length)); fs.Write(fileReceiveByte, 0, length); if (fileReceiveByte.Length == 0) { break; } } fs.Close(); } else { Console.WriteLine("Canceled"); byte[] operationByte = BitConverter.GetBytes(0); clientSocket.Send(operationByte); } clientSocket.Shutdown(SocketShutdown.Both); |
Das Programm schmiert immer ab, sobald es die Datei empfangen soll!
Wieso?
Ist der Ansatz mit FileStream behaupt richtig oder gibt es eine bessere Variante?
Da Dateien in größe von 2 GB den kompletten Speicher belegen würden, habe ich versucht die Datei Stückweise in 50MB Abschnitten zu verschicken.
C#-Quelltext
1:
| internal int length = 1024 * 50000; |
Ich hoffe es kann mir jemand weiterhelfen. :(
Danke schonmal
Grüße
Kha - So 02.05.10 17:09
Gibt es auch eine Abschmier-Exception?
PS: Warum überhaupt Sockets und nicht TcpClient/Listener?
/edit: Warum Read(...) == 0?
Red2Devil - So 02.05.10 18:15
klar, das Exception Handling wollte ich auch noch einbauen, jedoch erstmal erfahren was das Programm mir als Fehler ausgibt!
Es gibt nun immer eine Socket.Exception, dass erst nach ner Zeit kommt - Wird wohl am TimeOut liegen und die Gegenüberliegende Seite die Verbindung beendet hat!
Aber die Datei wird angelegt, aber es kommt kein Byte an! Sprich es existiert dann eine 0 Byte- Datei mit richtigen namen auf dem Server PC.
----
Das "while (fs.Read(fileSendByte, 0, length) == 0)" habe ich geschrieben, da ich dachte, es würde mir grundsätzlich die gelesenen Bytes zurückgeben und sobald 0 kommt, soll die While-Schleife abgebrochen werden.
Möchte ja wie gesagt größere Dateien in Stücken verschicken!
Wie könnte man es sonst lösen?
----
Was ist am TcpClient bzw TcpListener denn besser als beim Socket? Es müsste doch auch so funktionieren oder?
Red2Devil - So 02.05.10 18:50
Kha hat folgendes geschrieben : |
Enthält die Exception denn keine Fehlerbeschreibung? Und in welcher Zeile? |
Kha hat folgendes geschrieben : |
Das stimmt schon, aber im Code hast du das genaue Gegenteil geschrieben ;) . |
Seitdem ich nun die While-Schleife von "==" auf "!=" geändert habe, kommt acuh die Exception nicht mehr. Er geht in die While-Schleife und gibt die entprechenden Strings in der Ausgabe aus.
Quelltext
1: 2: 3:
| Laenge: 2005485 Send: 51200000 Der Thread 0x12cc hat mit Code 0 (0x0) geendet. |
Nun muss ich noch rausfinden, wieso die Bytes nicht wirklich in die Datei geschrieben werden. Bleibt trotzdem weiterhin eine 0-Byte Datei übrig :(
Sorry, für die wahrscheinlich primitiven Probleme, jedoch hab ich vorher noch nie mit sockets und Dateien gearbeitet! Bin noch in der Lernphase ;)
----
Kha hat folgendes geschrieben : |
Socket hat folgendes geschrieben: | If you are writing a relatively simple application and do not require maximum performance, consider using TcpClient, TcpListener, and UdpClient. These classes provide a simpler and more user-friendly interface to Socket communications. |
|
Gut =) hab mir das soweit mal angeschaut! Jedoch ist noch sinnvoll die Sockets nun noch in TCPListener und TCPClient zu ändern?
Kha - So 02.05.10 20:00
Hast du mit dem Debugger/... schon einmal überprüft, ob der Server überhaupt beendet wird? Sollte er nämlich eigentlich nicht (bzw.
Receive einen Timeout melden), solange du im Client nicht
Shutdown aufrufst:
Zitat: |
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer. If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes. |
Red2Devil hat folgendes geschrieben : |
Gut =) hab mir das soweit mal angeschaut! Jedoch ist noch sinnvoll die Sockets nun noch in TCPListener und TCPClient zu ändern? |
Das musst du anhand des erwarteten restlichen Aufwandes wohl selbst entscheiden :) .
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!