Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#] Socket.BeginReceive wordt niet opnieuw afgevuurt

Pagina: 1
Acties:

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
Beste medetweakers.

Ik heb een socket, dewelke een connection ontvangt, en dan begint te wachten op data.

Dat werkt mooi, en daarvoor heb ik de volgende code:

C#:
1
2
3
4
5
6
7
8
9
10
11
        /// <summary>
        /// starts a new receive on the socket
        /// </summary>
        /// <param name="socket">the System.Net.Sockets.Socket</param>
        private void WaitForData(Socket socket)
        {
            SocketPacket socketPacket = new SocketPacket();
            socketPacket.Socket = socket;

            socket.BeginReceive(socketPacket.Buffer, 0, SocketPacket.BufferSize, 0, new AsyncCallback(OnDataReceived), socketPacket);
        }


Werkt leuk.

Mijn SocketPacket is dit:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    /// <summary>
    /// SocketPacket, send from the socket to the handler
    /// </summary>
    class SocketPacket
    {
        /// <summary>
        /// Constants
        /// </summary>
        public const int BufferSize = 1024;

        /// <summary>
        /// Properties
        /// </summary>
        public System.Net.Sockets.Socket Socket { get; set; }
        public byte[] Buffer { get; set; }
        public MemoryStream Stream { get; set; }

        public SocketPacket()
        {
            this.Socket = null;
            this.Buffer = new byte[BufferSize];
            this.Stream = new MemoryStream();
        }
    }


Werkt ook perfect.

Maar nu: zoals ge in WaitForData kunt zien is de CallBack 'OnDataReceived'.

Deze wordt dus mooi afgevuurd bij inkomende data, de Stream wordt opgevult, en wordt opnieuw meegestuurd met de CallBack. Maar!!! Volgens het voorbeeld op http://msdn2.microsoft.com/en-us/library/fx6588te.aspx (scroll naar beneden voor C# voorbeeld) en op http://msdn2.microsoft.com/en-us/library/w7wtt64b.aspx zou hij die delegate opnieuw moeten afvuren.

Dat doet ie dus niet, waardoor m'n code niets doet. Ik heb al tig dingen proberen aan te passen, maar no go, ik zit muur vast. Google helpt mij ook niet, en de debugger ook niet. Ik heb al tig keer regel per regel gedebugged, en alles lijkt in orde. Ik krijg mooi het pakketje binnen (grootte varieert als ik de tekst veranderd), maar hij wil het niet parsen.

de OnDataReceived CallBack:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        private void OnDataReceived(IAsyncResult async)
        {
            SocketPacket socketPacket = (SocketPacket)async.AsyncState;
            Socket socket = socketPacket.Socket;

            int read = socket.EndReceive(async);

            if (read > 0)
            {
                socketPacket.Stream.Write(socketPacket.Buffer, 0, read);
                socket.BeginReceive(socketPacket.Buffer, 0, SocketPacket.BufferSize, 0, new AsyncCallback(OnDataReceived), socketPacket);
            }
            else
            {
                Message message = (Message)this.binaryFormatter.Deserialize(socketPacket.Stream);
                this.receiveDelegate(message);

                this.WaitForData(this.socketWorker);
            }
        }


Kan iemand mij hier schoppen in de goede richting?

Going for adventure, lots of sun and a convertible! | GMT-8


  • whoami
  • Registratie: December 2000
  • Laatst online: 13:42
Wat wil je nu eigenlijk ?
Dat je socket 'oneindig' blijft luisteren ofzo ?

Dan heb je zowiezo een loop nodig.

Of wat bedoel je eigenlijk, want ik volg je niet ...

https://fgheysels.github.io/


  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
whoami schreef op donderdag 06 maart 2008 @ 23:03:
Wat wil je nu eigenlijk ?
Dat je socket 'oneindig' blijft luisteren ofzo ?

Dan heb je zowiezo een loop nodig.

Of wat bedoel je eigenlijk, want ik volg je niet ...
Ja, die socket moet luisteren totdat het packetje helemaal binnen is, en dan deserializen.

Als het packetje nog niet helemaal binnen is doet hij toch opnieuw een beginReceive in het laatste stukje code (regel 11). Zelfs dat doet hij niet helemaal?

Going for adventure, lots of sun and a convertible! | GMT-8


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17:20

Janoz

Moderator Devschuur®

!litemod

Ik ken .NET niet, maar sockets wel. De socket zelf heeft, in tegenstelling tot bijvoorbeeld een filestream, geen enkele manier om door te hebben of alle data binnen is. Het kan best zijn dat je op een gegeven moment de buffer probeert uit te lezen, maar dat deze leeg is omdat het laatste stuk data nog onderweg is. Het controleren of alles binnen is zul je dus in je protocol op moeten lossen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Die OnDataReceived is een asynchrone callback, can de MemoryStream daar tegen?

Anders laat de rest van je code weg en kijk of alleen het socket gedeelte werkt.

[edit]
Op zich is het een beetje vreemd om de netwerk communicatie asynschroon te doen om vervolgens een synchrone Memorystream te gebruiken. Is dat wat je wilt?

[ Voor 33% gewijzigd door farlane op 07-03-2008 09:06 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

OnDataReceived zal worden aan geroepen zodat de buffer is gevuld. Echter BeginReceived is in feite voltooid zodra het 'size' (derde parameter) bytes in de buffer array heeft geplaatst en wordt de IAsync delegate uitgevoerd (wat jouw onDataReceived) is. Je zult echt via een loop meerdere keren BeginReceive moeten aanroepen.

Kijk anders een naar de 'simpele' netwerk protocollen zoals POP3 en SMTP. Let daarbij vooral op de techniek waarmee in smtp wordt aangegeven dat het bericht (data) naar de stream is geschreven.

If it isn't broken, fix it until it is..


  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Topicstarter
farlane schreef op vrijdag 07 maart 2008 @ 09:03:
Die OnDataReceived is een asynchrone callback, can de MemoryStream daar tegen?

Anders laat de rest van je code weg en kijk of alleen het socket gedeelte werkt.

[edit]
Op zich is het een beetje vreemd om de netwerk communicatie asynschroon te doen om vervolgens een synchrone Memorystream te gebruiken. Is dat wat je wilt?
Indien het object wat binnenkomt te groot is, moet dat geappended worden aan die memorystream. Indien het compleet binnen is, wordt de memorystream opnieuw gecreeert :) dus dat is in orde.

Going for adventure, lots of sun and a convertible! | GMT-8


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Niemand_Anders schreef op vrijdag 07 maart 2008 @ 09:15:
OnDataReceived zal worden aan geroepen zodat de buffer is gevuld. Echter BeginReceived is in feite voltooid zodra het 'size' (derde parameter) bytes in de buffer array heeft geplaatst en wordt de IAsync delegate uitgevoerd (wat jouw onDataReceived) is. Je zult echt via een loop meerdere keren BeginReceive moeten aanroepen.
OnDataReceived wordt al aangeroepen als er meer dan nul bytes in de buffer geplaatst zijn. Vervolgens lees je bytes uit die buffer (wat wel of niet alle data is die je wilt hebben). Zolang de receive meer dan 0 bytes leest blijf je BeginReceive aanroepen ( dat is de loop waar je op doelt ).

Als de callback wordt aangeroepen en read levert <= 0 op betekent dat dat de verbinding is verbroken of er iets fout is gegaan.

Wat de TS echter nog mist is:
- Een manier om de ontvanger duidelijk te maken dat hij kan stoppen met BeginReceive aan te roepen, onafhankelijk van het aantal bytes dat in de buffer is geplaatst. ( Wat je ook al aangeeft )
- Een timeout mechanisme ( bijvoorbeeld een timer die je start bij je eerste aanroep naar BeginReceive en telkens opnieuw start als je callback wordt aangeroepen en je nog niet het hele object binnenhebt )
Indien het object wat binnenkomt te groot is, moet dat geappended worden aan die memorystream.
Is dat wat Write doet dan, als je 'em aanroept vanuit een asynchrone callback?

[ Voor 8% gewijzigd door farlane op 07-03-2008 14:53 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1