Autor Beitrag
Red2Devil
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 02.05.10 16:41 
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:

ausblenden 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:

ausblenden volle Höhe 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.

ausblenden C#-Quelltext
1:
internal int length = 1024 * 50000;					


Ich hoffe es kann mir jemand weiterhelfen. :(

Danke schonmal

Grüße
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 02.05.10 18:24 
user profile iconRed2Devil hat folgendes geschrieben Zum zitierten Posting springen:
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!
Enthält die Exception denn keine Fehlerbeschreibung? Und in welcher Zeile?

user profile iconRed2Devil hat folgendes geschrieben Zum zitierten Posting springen:
da ich dachte, es würde mir grundsätzlich die gelesenen Bytes zurückgeben und sobald 0 kommt, soll die While-Schleife abgebrochen werden.
Das stimmt schon, aber im Code hast du das genaue Gegenteil geschrieben ;) .

user profile iconRed2Devil hat folgendes geschrieben Zum zitierten Posting springen:
Was ist am TcpClient bzw TcpListener denn besser als beim Socket?
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.

_________________
>λ=
Red2Devil Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 02.05.10 18:50 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Enthält die Exception denn keine Fehlerbeschreibung? Und in welcher Zeile?

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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.

ausblenden 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 ;)

----
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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.


user profile iconRed2Devil hat folgendes geschrieben Zum zitierten Posting springen:
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 :) .

_________________
>λ=