Autor Beitrag
reox
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: Mo 09.02.09 22:41 
Ich muss derzeit für die Schule mit C# ein Projekt machen. Das ganze soll übers Netzwerk ein paar Sachen senden. Das Problem: Ich weiß nie wie groß das ganze wird, da ich eine gewisse anzahl von Objekten anfordere und nicht weiß wie groß die dann werden.
Wir haben das ganze so beigebracht bekommen, dass ich einen Byte[] Buffer erstelle und den dann über einen networkStream sende.
Mal als Beispiel:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
byte[] inBuffer = new byte[65535];
client = new TcpClient(srv, port);
NetworkStream stream = client.GetStream();
byte[] outBuffer = Encoding.ASCII.GetBytes("bla bla blub");
stream.Write(outBuffer, 0, outBuffer.Length);
stream.Read(inBuffer, 0, inBuffer.Length);

nun hab ich lange mit Java gearbeitet und hab dort immer Streams verwendet, die keinen Buffer hatten (kommt mir so vor...) dort konnte ich von einem Stream in einen anderen Stream schreiben, ohne irgendwelche byte[] zu erstellen.
Gibt es diese Möglichkeit in C# auch? Das würde mir sehr weiterhelfen!

Auch noch eine Frage die in das gleiche gebiet fällt. Ich würde gerne der einfachhalt habler keine Strings übers Netzwerk senden und die dann wieder entwursten, sondern einfach ein Objekt Serialisieren und am Server wieder deserialisieren. Das gleiche dann auch wieder zum Client zurück.
Ich hab in meinem Skriptum davon nix stehen, dort wird nur behandelt wie man in Files schreibt. würde es im prinzip so gehen?
ausblenden C#-Quelltext
1:
2:
3:
4:
client = new TcpClient(srv, port);
NetworkStream stream = client.GetStream();
IFormatter bifo = new BinaryFormatter();
bifo.Serialize(stream, ginf);
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Di 10.02.09 11:22 
user profile iconreox hat folgendes geschrieben Zum zitierten Posting springen:

Auch noch eine Frage die in das gleiche gebiet fällt. Ich würde gerne der einfachhalt habler keine Strings übers Netzwerk senden und die dann wieder entwursten, sondern einfach ein Objekt Serialisieren und am Server wieder deserialisieren. Das gleiche dann auch wieder zum Client zurück.
Ich hab in meinem Skriptum davon nix stehen, dort wird nur behandelt wie man in Files schreibt. würde es im prinzip so gehen?

"Im Prinzip" sollte es in der Tat genau so gehen. Ein FileStream wird insofern vermutlich nicht anders behandelt als ein MemoryStream oder ein NetworkStream - alles ist von Stream abgeleitet.

Aber schlag mich bitte nicht, wenn es an irgendeiner Besonderheit scheitern sollte - soviel Netzwerk-Kenntnisse habe ich nicht.

Viel Erfolg! Jürgen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Di 10.02.09 11:36 
Hallo,

ja das geht genau so und auf der anderen Seite einfach deserialisieren, so dass die Objekte raus purzeln :D (hab ich auch schon so gemacht)

Und dann am besten mit Visitor-Pattern verarbeiten... das rockt ;)

Gruß Daniel

@JüTho: dieses mal warst du schneller ;)
reox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: Di 10.02.09 19:34 
ok irgendwie gehts jetzt. Ich hab nur nen doofes Problem mitm GC:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
xmlsr = new XmlSerializer(typeof(GCDBInformation));
client = new TcpClient(srv, port);
sw = new StreamWriter(client.GetStream());
sr = new StreamReader(client.GetStream());
xmlsr.Serialize(sw, ginf);
sw.Close();
xmlsr = new XmlSerializer(typeof(GoogleMapsMap));
GoogleMapsMap map = (GoogleMapsMap)xmlsr.Deserialize(sr);
Browser.DocumentText = map.generateHTML();

Das ist jetzt nen Ausschnitt von meinem Client. Das Problem dabei: wenn ich den StreamReader initialisiere bekomm ich die Meldung das der TcpClient nicht mehr existiert. Kann das denn sein? Irgendwie doch blöd was der GC da macht... Ich hab aber das gleiche mit
ausblenden C#-Quelltext
1:
2:
sw = new StreamWriter(client.GetStream());
sr = new StreamReader(client.GetStream());

hier schon im Forum gelesen...
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 10.02.09 20:04 
Das klingt merkwürdig, könntest du mal die exakte Fehlermeldung posten? Außerdem solltest du den Writer wahrscheinlich erst am Ende schließen.

_________________
>λ=
reox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: Di 10.02.09 21:28 
hat nen bischen gedauert, hab noch an einem anderen Problem gehangen...

Das problem hat sich nun irgendwie geändert... Der server bekommt vom Client keine Daten mehr:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
[SERVER] [Message][11.02.2009 00:09:28] - Server gestartet
[SERVER] [Message][11.02.2009 00:09:33] - Client connected
[SERVER] [Message][11.02.2009 00:09:33] - Awaiting Data...
[127.0.0.1] [Message][11.02.2009 00:09:35] - Anfrage an den Server gesendet
[SERVER] [Error][11.02.2009 00:09:46] - System.InvalidOperationException: Fehler im XML-Dokument (7,3). ---> System.IO.IOException: Von der Übertragungsverbindung können keine Daten gelesen werden: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht ordnungsgemäß reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat. ---> System.Net.Sockets.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht ordnungsgemäß reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
   bei System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   bei System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   bei System.IO.StreamReader.ReadBuffer(Char[] userBuffer, Int32 userOffset, Int32 desiredChars, Boolean& readToUserBuffer)
   bei System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
   bei System.Xml.XmlTextReaderImpl.ReadData()
   bei System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   bei System.Xml.XmlTextReaderImpl.Read()
   bei System.Xml.XmlTextReader.Read()
   bei System.Xml.XmlReader.ReadEndElement()
   bei System.Xml.Serialization.XmlSerializationReader.ReadEndElement()
   bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderGCDBInformation.Read2_GCDBInformation(Boolean isNullable, Boolean checkType)
   bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderGCDBInformation.Read3_GCDBInformation()
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   bei System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)
   bei GCDBv2.Handler.Run() in F:\Eigene Dateien\Visual Studio 2008\Projekt_2HJ\GCDBv2\GCDBv2\Handler.cs:Zeile 73.


Am Client:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
try
            {
                xmlsr = new XmlSerializer(typeof(GCDBInformation));
                client = new TcpClient("localhost", port);
                sw = new StreamWriter(client.GetStream());
                sr = new StreamReader(client.GetStream());
                Thread.Sleep(2000);
                xmlsr.Serialize(sw, ginf);
                sw.Flush();
                Program.Log().Log("Message""Anfrage an den Server gesendet");
                xmlsr = new XmlSerializer(typeof(GoogleMapsMap));
                GoogleMapsMap map = (GoogleMapsMap)xmlsr.Deserialize(sr);
                Browser.DocumentText = map.generateHTML();
                Program.Log().Log("Message""Anfrage vom Server bearbeitet");
                // sw.Close();
                //sr.Close();
            }


Und am Server:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
try
            {
                le.Log("Message""Client connected to Socket");
                ArrayList caches = new ArrayList();

                xmlsr = new XmlSerializer(typeof(GCDBInformation));
                StreamReader sr = new StreamReader(tcpClient.GetStream());
                StreamWriter sw = new StreamWriter(tcpClient.GetStream());

                le.Log("Message""Awaiting Data...");
                GCDBInformation daten = (GCDBInformation)xmlsr.Deserialize(sr); // das ist zeile 73
                
                GeoCoordinate center = new GeoCoordinate(daten.Latitude, daten.Longitude);
                double max_dist = daten.Radius;
                le.Log("Message""Data received... creating map");

                GoogleMapsMap gmm = new GoogleMapsMap(512512, center);
                xmlsr = new XmlSerializer(typeof(GoogleMapsMap));
                // xmlsr.Serialize(sw, gmm);
            }


also irgendwas mach ich falsch oO
reox Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 37



BeitragVerfasst: Mi 11.02.09 15:57 
Ich hab ein wenig geforscht und glaube ich weiß nun warum es nicht geht...
Ich sage dem Client er soll den StreamWriter Fushen, was er aber nicht macht. Beende ich das program, empfängt der Server die Daten und beendet die Verbindung. Die Daten sind dann am Server vorhanden, der Thread am Server wird aber beendet, da der Client ja disconnected ist. Wie soll das dann gehen, dass ich eine Duplex Verbindung aufbaue und Daten über den StreamReader und StreamWriter auf einem Sockel versende? Wenn ich den Stream Close wird der Socket ebenfalls beendet...
Irgendwie ist das komisch... Muss ich nen neuen Sockel für die andere Verbindung aufmachen? Wäre ja irgendwie doof...
Der Log dazu:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
[SERVER] [Message][11.02.2009 14:54:56] - Server gestartet
[127.0.0.1] [Message][11.02.2009 14:55:01] - Button Clicked... generating object
[SERVER] [Message][11.02.2009 14:55:01] - Client connected to Socket
[127.0.0.1] [Message][11.02.2009 14:55:01] - Anfrage an den Server gesendet
[SERVER] [Message][11.02.2009 14:55:01] - Awaiting Data... // Hier wird der Client beendet...
[SERVER] [Message][11.02.2009 14:55:03] - received: 100 - 1000 - 48,209206 - 16,372778 // danach sollte noch eine Log Message kommen, die aber nicht mehr drin ist, da der Thread am Server beendet wird.