myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Netzwerktechnologien » Datentransfer über TCP Socket
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Datentransfer über TCP Socket

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Geraldo23 Geraldo23 ist männlich
myCSharp.de-Mitglied

Dabei seit: 16.07.2004
Beiträge: 19
Entwicklungsumgebung: Visual Studio .NET 2003
Herkunft: Österreich


Geraldo23 ist offline

Datentransfer über TCP Socket

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!
Ich habe folgendes Problem: Ich programmiere gerade ein Windows Service welches auf einem Exchange Server läuft und auf einem bestimmten Port wartet und dort XML Streams entgegennimmt und diese dann auswertet und Kontakte am Exchange Server anlegt. Also das funktioniert mit einer kleinen Menge an Daten, sobald ich aber eine große Menge an Daten schicke möchte funktioniert es nicht mehr, ich vermute mal dass das Service den XML Stream schneller ausdwertet als die Daten da sind, daher bekomme ich immer die Fehlermeldung dass sich ein ungültiges Zeichen im Stream befindet.
Wenn ich das Service jedoch am Localhost teste funktioniert alles.

Hier ist der Listen Code des Services:

C#-Code:
protected void StartListen()
{
Console.WriteLine("Working Thread: {0} ",Thread.CurrentThread.Name);
    objSocket = listener.AcceptSocket();
    NetworkStream ns = new NetworkStream(objSocket);
    StreamReader sr = new StreamReader(ns);

                while(true)
    {
             if(objSocket.Connected)
        {
        StringBuilder objStrBuilder = new StringBuilder();
        byte[] byteReceived = new byte[1024];
//Es können jedoch auch mehr Daten übertragen werden

                     Int32 nReceived = objSocket.Receive(byteReceived,byteReceived.Length,0);
        objStrBuilder.Append(System.Text.Encoding.ASCII.GetString(byteReceived,0,nReceived));

        EndPoint ep = objSocket.RemoteEndPoint;
        string ip = ep.ToString();

        while(!(nReceived<byteReceived.Length))
        {
        nReceived = objSocket.Receive(byteReceived,byteReceived.Length,0);
                                                 objStrBuilder.Append(System.Text.Encoding.ASCII.GetString(byteReceived,0,nReceived));
        }

        string noError = "Erfolgreich empfangen";
        Byte[] message = System.Text.Encoding.ASCII.GetBytes(noError.ToCharArray());
        objSocket.Send(message,message.Length,0);

        Console.WriteLine("Nachricht von " + ip + " erhalten!");

        checkXML(objStrBuilder);
//dort wird der XLM Stream ausgewertet    
        }
        else
        {
        string error = "Keine Verbindung";
        Byte[] errorMsg = System.Text.Encoding.ASCII.GetBytes(error.ToCharArray());
        objSocket.Send(errorMsg,errorMsg.Length,0);
        }
    }
}

An was könnte das liegen und wie könnte ich das Problem lösen?
Vielen Dank für eure Hilfe!

Mfg
Geri
16.07.2004 09:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
r00t r00t ist männlich
myCSharp.de-Mitglied

avatar-199.gif


Dabei seit: 05.05.2004
Beiträge: 139
Entwicklungsumgebung: VS.NET 03 C#
Herkunft: Schwäbisch Gmünd


r00t ist offline Füge r00t Deiner Kontaktliste hinzu MSN-Passport-Profil von r00t anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

also das mit stream ist generell sone sache, würde ich nicht empfehlen (haste ja gesehen). andere gründe könnten auch zb unterbrechungen sein.

erstellt doch ein tmpXmlDatei die du dann nach erfolgreichen erhalt (kann auch zb durch validation erzielt werden muss aber nicht) erst DANN auswertest.

gruß,

r00t
16.07.2004 10:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Scordo
myCSharp.de-Mitglied

Dabei seit: 15.07.2004
Beiträge: 18
Entwicklungsumgebung: VS 2003 Enterprise Architect
Herkunft: Nürnberg


Scordo ist offline Füge Scordo Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

sagen wir mal es kommen 2000 zeichen rein :

Code:
1:
Int32 nReceived = objSocket.Receive(byteReceived,byteReceived.Length,0);

dann steht in nReceived <-- 1024

dann ergibt

Code:
1:
while(!(nReceived<byteReceived.Length))

false weil (nReceived<byteReceived.Length) gleich true ist
da 1024 == 1024 heisst also für dateien unter 1kb klappt es
.. drüber nicht

[email protected] SCO
16.07.2004 10:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
r00t r00t ist männlich
myCSharp.de-Mitglied

avatar-199.gif


Dabei seit: 05.05.2004
Beiträge: 139
Entwicklungsumgebung: VS.NET 03 C#
Herkunft: Schwäbisch Gmünd


r00t ist offline Füge r00t Deiner Kontaktliste hinzu MSN-Passport-Profil von r00t anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
byte[] byteReceived = new byte[1024];
//Es können jedoch auch mehr Daten übertragen werden

ich habe das so verstanden als wenn auch 1024 Zeichen abgeschickt werden, und deswegen kommen auch 1024 an. "Es können jedoch auch mehr Daten übertragen werden".

@scordo
das was du das schreibst müßte dann auch für den localhost gelten...
16.07.2004 10:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Geraldo23 Geraldo23 ist männlich
myCSharp.de-Mitglied

Dabei seit: 16.07.2004
Beiträge: 19
Entwicklungsumgebung: Visual Studio .NET 2003
Herkunft: Österreich

Themenstarter Thema begonnen von Geraldo23

Geraldo23 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es steht nicht fest wieviele Daten geschickt werden. Wie kann ich das am besten realisieren dass das Service Daten entgegennimmt ohne eine bestimmte Größe festlegen zu müssen?

Die Methode checkXML soll erst aufgerufen werden wenn wirklich alle Daten da sind.
16.07.2004 11:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Scordo
myCSharp.de-Mitglied

Dabei seit: 15.07.2004
Beiträge: 18
Entwicklungsumgebung: VS 2003 Enterprise Architect
Herkunft: Nürnberg


Scordo ist offline Füge Scordo Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
ich habe das so verstanden als wenn auch 1024 Zeichen abgeschickt werden, und deswegen kommen auch 1024 an. "Es können jedoch auch mehr Daten übertragen werden".

genau das ist es ja .. wenn 2000 zeichen geschickt werden dann werden beim ersten senden 1024 zeichen übertragen und beim 2. mal 976 Zeichen. Er steigt aber schon beim ersten mal aus weil die while-bedinguing nicht greift.

[email protected] SCO

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Scordo am 16.07.2004 11:34.

16.07.2004 11:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Scordo
myCSharp.de-Mitglied

Dabei seit: 15.07.2004
Beiträge: 18
Entwicklungsumgebung: VS 2003 Enterprise Architect
Herkunft: Nürnberg


Scordo ist offline Füge Scordo Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

wenn es dir weiterhilft :

 download

dort findest du von mir geschriebene Klassen (Server + Client) die haben events fürs connecten .. disconnecten .. receiven usw.

[email protected] SCO
16.07.2004 11:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
r00t r00t ist männlich
myCSharp.de-Mitglied

avatar-199.gif


Dabei seit: 05.05.2004
Beiträge: 139
Entwicklungsumgebung: VS.NET 03 C#
Herkunft: Schwäbisch Gmünd


r00t ist offline Füge r00t Deiner Kontaktliste hinzu MSN-Passport-Profil von r00t anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

wieso hast du das so programmiert?

1. Lösung: schicke wirklich nur deine 1024 bytes ab
2. Lösung: mach das mit der TmpXmlFile
3. Lösung: while(!(nReceived<1))
4. evtl. Lösung: du änderst diese zeile
objSocket.Receive(byteReceived); // byte[] byteReceived = null;

Zitat:
Wenn ich das Service jedoch am Localhost teste funktioniert alles.

und warum funktioniert das trotzdem?


gruß,

r00t
16.07.2004 12:04 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CarstenP CarstenP ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2004
Beiträge: 65
Entwicklungsumgebung: VS.NET 2003 EA
Herkunft: Berlin


CarstenP ist offline Füge CarstenP Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Auf dem localhost dürfte es deswegen funktionieren, weil dort keine Leitungsprobleme (Collisions, Delays, Timeouts) auftreten. Das sieht in einem realen Netz ganz anders aus.

Wenn die MTU < 1024 steht, dann kommen nie 1024 Bytes auf einmal an, sondern immer maximal das, was in der MTU definiert ist. (MTU = maximum transmission unit, dazu eine gute  Erklärung von D. Ruf.) Das ist zwar nicht üblich, aber aus welchem Grund auch immer kann das durchaus so sein. Außerdem beachte man das "M", sprich: trotz MTU von 1518 oder 1492 kann es passieren, dass IP-Pakete fragmentiert werden.

Die Lösung besteht also darin, den Socket so lange auszulesen, bis nix mehr kommt bzw. bis die Gegenstelle die Verbindung schließt bzw. bis man ein Timeout auslöst bzw. er eine Ausnahme wirft. Ansonsten Zustimmung zur obigen Aussage, dass Streams "böse" sind.
19.07.2004 12:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
r00t r00t ist männlich
myCSharp.de-Mitglied

avatar-199.gif


Dabei seit: 05.05.2004
Beiträge: 139
Entwicklungsumgebung: VS.NET 03 C#
Herkunft: Schwäbisch Gmünd


r00t ist offline Füge r00t Deiner Kontaktliste hinzu MSN-Passport-Profil von r00t anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Original von CarstenP
Auf dem localhost dürfte es deswegen funktionieren, weil dort keine Leitungsprobleme (Collisions, Delays, Timeouts) auftreten. Das sieht in einem realen Netz ganz anders aus.

zuerst mal thx für die nette info.

bei localhost sollte doch erst recht der fehler auftauchen sollte weil wegen der relative "reibungslosen" transmission. oder?


gruß, r00t
19.07.2004 16:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CarstenP CarstenP ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2004
Beiträge: 65
Entwicklungsumgebung: VS.NET 2003 EA
Herkunft: Berlin


CarstenP ist offline Füge CarstenP Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Warte, habe ich Stuss erzählt? Ich hasse sinnfreie Verneinung in logischen Ausdrücken. Moment... verwundert

while(!(nReceived<byteReceived.Length))

<=>

while (nReceived >= byteReceived.Length)

(">" kann nicht sein, also...)

<=>

while (nReceived == byteReceived.Length)

d.h.: Solange immer der gesamte Buffer beim Lesen gefüllt wird, geht es weiter. Der Socket kriegt also z.B. 1518 Bytes - 14 Bytes Ethernet-Header - 4 Bytes Prüfsumme - 40 Bytes TCP-Header = 1460 Bytes Nutzdaten.

Davon werden 1024 an den Buffer übergeben, und asynchron wird der Socket wieder auf 1024 aufgefüllt usw., bis über den Socket alles geholt ist. Der letzte Block ist dann < 1024, und die while-Schleife endet.

Zur Prüfung meiner o.g. "Theorie" sollte man im Code die 1024 mal auf was richtig Großes verändern und mit dem localhost testen. Das kann dann fehlschlagen, muss es aber nicht, weil die Daten lokal ja huschhusch übertragen werden. Deswegen sollte man noch einen zweiten Test fahren mit einer sehr kleinen Paketgröße (64 Bytes oder sowas) und dann übers Netz probieren.

Schlauer wäre es natürlich, den Unfug zu lassen und das Auslesen des Sockets gleich richtig zu schreiben, also darauf zu prüfen, ob der Socket noch Daten kriegt.
19.07.2004 16:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Scordo
myCSharp.de-Mitglied

Dabei seit: 15.07.2004
Beiträge: 18
Entwicklungsumgebung: VS 2003 Enterprise Architect
Herkunft: Nürnberg


Scordo ist offline Füge Scordo Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

generell sind die NetzworkStreams nicht wirklich zu empfehlen, in den meisten Fällen sollte man doch lieber auf die Low-Level-Socket-Implementierung zurück greifen und sich selbst was vernünftiges schreiben.

Is aber nicht so einfach da bei den Basis-Komponenten wirklich nur das nötigste implementiert ist und man ziemlich viel wissen bzw. sich anlesen muss um diese zu gebrauchen.


[email protected] SCO
19.07.2004 20:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CarstenP CarstenP ist männlich
myCSharp.de-Mitglied

Dabei seit: 19.07.2004
Beiträge: 65
Entwicklungsumgebung: VS.NET 2003 EA
Herkunft: Berlin


CarstenP ist offline Füge CarstenP Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Original von Scordo
generell sind die NetzworkStreams nicht wirklich zu empfehlen, in den meisten Fällen sollte man doch lieber auf die Low-Level-Socket-Implementierung zurück greifen und sich selbst was vernünftiges schreiben.

Is aber nicht so einfach da bei den Basis-Komponenten wirklich nur das nötigste implementiert ist und man ziemlich viel wissen bzw. sich anlesen muss um diese zu gebrauchen.

Jeppa, völlige Zustimmung. Das Framework gaukelt einem vor, IP wäre so schmuck einfach, dass das ein Kinderspiel sei, aber denkste. Ich würde mal sagen, wer noch keinen kleinen Server, der über IP arbeitet, in C geschrieben hat, inklusive fork() und solchen Späßen, wird sich auch mit dem Framework schwer tun, wenn er eine stabile, zuverlässige und performante Lösung entwickeln will.
22.07.2004 10:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 16 Jahre.
Der letzte Beitrag ist älter als 16 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 20.10.2020 08:18