AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke C# Probleme mit Datenempfang über asynchronen Socket
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit Datenempfang über asynchronen Socket

Ein Thema von Meflin · begonnen am 10. Sep 2010 · letzter Beitrag vom 11. Sep 2010
 
Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#1

Probleme mit Datenempfang über asynchronen Socket

  Alt 10. Sep 2010, 18:42
Hi,

ich versuche derzeit, einen asynchronen (TCP) Socket Client zu schreiben (C#). Der Server sendet serialisierte Objekte, wobei pro Objekt die ersten 4 Byte die länge des darauffolgenden Objekts verraten.

Der relevante Codeteil:
Code:
public class StateObject
{
    public Socket workSocket = null;
    public const int BufferSize = 2048;
    public byte[] buffer = new byte[BufferSize];
    public MemoryStream receivedObject = null;
    public bool lengthRead = false;
    public long dataLength = 0;
}

private void Receive()
{
    try
    {
        StateObject state = new StateObject();
        state.workSocket = client;

        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReceiveCallback), state);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.workSocket;

        int bytesRead = client.EndReceive(ar);
        if (bytesRead > 0)
        {
            if (!state.lengthRead)
            {
                state.dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(state.buffer, 0));
                state.lengthRead = true;
                state.receivedObject = new MemoryStream(/*Convert.ToInt32(state.dataLength) + 4*/);
            }
            state.receivedObject.Write(state.buffer, 0, bytesRead);

            if (state.receivedObject.Length > state.dataLength)
            {
                Console.WriteLine("Receive done. Received {0} bytes, expected {1}.", state.receivedObject.Length, state.dataLength);
                Receive();
            }
            else
            {
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
        }
        else
        {
            Console.WriteLine("Connection closed by server.");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}
Allerdings funktioniert das ganze nicht so wie ich mir das denke. Im Moment müssten immer 4 Bytes mehr ankommen, als vermutet (da die Bytes für die Längenangabe mit in den Objektbuffer geschrieben werden).

Beispielausgabe des Programms:
Code:
Socket connected to xxx.
Sent 102 bytes to server.
Sent 48 bytes to server.
Receive done. Received 6836 bytes, expected 5714. <--
Receive done. Received 168 bytes, expected 164.
Sent 76 bytes to server.
Receive done. Received 128 bytes, expected 124.
Receive done. Received 240783 bytes, expected 240634. <--
Receive done. Received 110 bytes, expected 106.
Receive done. Received 125 bytes, expected 121.
Receive done. Received 138 bytes, expected 134.
Receive done. Received 121 bytes, expected 117.
Receive done. Received 118 bytes, expected 114.
Receive done. Received 134 bytes, expected 130.
Receive done. Received 129 bytes, expected 125.
Receive done. Received 296 bytes, expected 292.
Receive done. Received 242 bytes, expected 110. <--
Receive done. Received 142 bytes, expected 138.
Receive done. Received 296 bytes, expected 292.
Wie kann das nun sein?
  1. Die Dekodierung des Längenwertes ist falsch. Wieso ist sie aber dann fast immer richtig?
  2. Im Receivebuffer überlagern sich nicht zusammengehörige Objekte. Aber das darf doch garnicht sein . Das sollte doch eigentlich das Protokoll (TCP) für mich erledigen. Dann wäre die Frage, wann GENAU dieser Callback eigentlich aufgerufen wird. Definitives dazu konnte ich nicht finden
  3. ?
Ich hoffe, irgendjemand kann Licht in mein Dunkel bringen... Im Endeffekt will ich doch nur einfach pro empfangenem Objekt einen Callback aufrufen
Leo S.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz