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

[C#] Socket "ziet" pakketjes niet toekomen

Pagina: 1
Acties:

  • CyberThijs
  • Registratie: Maart 2004
  • Laatst online: 10:22
Ik ben bezig met het ontwikkelen van een MSNBot die oorspronkelijk gebruik maakte van DotMSN om te communiceren met het .Net Messenger-netwerk. Helaas is deze library wat out-of-date, dus besloot 'k hem zelf maar op te waarderen naar het laatste protocol (MSNP11).

Nu zit ik met het volgende probleem:
In ongeveer 75% van de gevallen dat ik mijn programma run (dus soms lukt het ook gewoonweg wel, maar het meest van al niet), loopt hij steeds vast na een bepaald commando. Het rare is dat dit probleem erg diep terugvoert als ik hem probeer te debuggen. Waar ik op uitkom is dat achter het pakket dat de socket ontvangt met dat commando, dat hij dan een hele tijd wacht op nieuwe data, en dan maar uiteindelijk de socket sluit (datalength = 0).

Echter, als ik met Etherdetect de inkomende packets in de gaten hou, dan zie ik dat er WEL nieuwe paketten toekomen, echter, de socket slaagt er blijkbaar niet in deze op te halen...

Hieronder de code die het probleem vormt:
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
        /// <summary>
        /// Starts an a-synchronous receive.
        /// </summary>
        /// <param name="socket"></param>
        protected virtual void BeginDataReceive(Socket socket)
        {
            // now go retrieve data 
            socketBuffer = new byte[socketBuffer.Length];
            socket.BeginReceive(socketBuffer, 0, socketBuffer.Length, SocketFlags.None, new AsyncCallback(EndReceiveCallback), socket);
        }

        /// <summary>
        /// The callback used by the Socket.BeginReceive method.
        /// </summary> 
        /// <param name="ar">The used socket.</param>
        protected virtual void EndReceiveCallback(IAsyncResult ar)
        {
            int cnt = 0;
            try
            {
                System.Diagnostics.Debug.Assert(messagePool != null, "Field messagepool must be defined in derived class of SocketMessageProcessor.");
                    
                Socket socket = (Socket)ar.AsyncState;
                SocketError error;
                cnt = socket.EndReceive(ar, out error);
                if(cnt == 0)
                {
                    Console.WriteLine("No data --> diconnected: " + error.ToString());
                    // No data is received. We are disconnected.
                    OnDisconnected();
                    return;
                }           

                // read the messages and dispatch to handlers
                using(BinaryReader reader = new BinaryReader(new MemoryStream(socketBuffer, 0, cnt)))
                {                    
                    messagePool.BufferData(reader);
                }
                while(messagePool.MessageAvailable)
                {
                    // retrieve the message
                    byte[] incomingMessage = messagePool.GetNextMessageData();

                    
                    // call the virtual method to perform polymorphism, descendant classes can take care of it
                    OnMessageReceived(incomingMessage);
                }

                // start a new read             
                BeginDataReceive(socket);
            }           
            catch(SocketException e)
            {               
                // close the socket upon a exception
                if(socket != null && socket.Connected) socket.Close();

                OnDisconnected();

                // an exception Occurred, pass it through
                if(ConnectionException != null)
                    ConnectionException(this, new ExceptionEventArgs(new ConnectivityException("SocketMessageProcessor encountered a socket exception while retrieving data. See the inner exception for more information.",e)));               
            }
            catch(ObjectDisposedException)
            {               
                // the connection is closed
                OnDisconnected();               
            }
            catch(Exception e)
            {               
                // close the socket upon a exception
                if(socket != null && socket.Connected) socket.Close();  
            
                if(Settings.TraceSwitch.TraceError)
                    System.Diagnostics.Trace.WriteLine(e.ToString() + "\r\n" + e.StackTrace + "\r\n", "SocketMessageProcessor");

                OnDisconnected();

                if(ConnectionException != null)
                    ConnectionException(this, new ExceptionEventArgs(new ConnectivityException("SocketMessageProcessor encountered a general exception while retrieving data. See the inner exception for more information.",e)));              
            }                       
        }

De volledige library staat ter jullie beschikking op http://www.tombotxp.net/WLMConnector.rar . Het bestand waar ik vermoed dat het probleem zit (en waar bovenstaande snippets uit komen dus) is Core\SocketMessageProcessor.cs


Het type socket dat gebruikt wordt is ProxySocket, afkomstig van Mentalis.org, echter, ik heb al heel dit stuk van de DotMSN-library herschreven mbv TcpClient, en ook dit bracht geen zoden aan de dijk :(


Alvast bedankt voor alle moeite! _/-\o_

  • CyberThijs
  • Registratie: Maart 2004
  • Laatst online: 10:22
*bump*

Niemand? :'(

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
Hmm rare bug. Zou het zo niet weten maar heb je een mogelijkheid om het op een ander systeem te testen?

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.


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
En als je het test zonder die proxysocket ? .. Als het dan wel werkt, dan weet je dat de fout bij de proxysocket zit ..

  • CyberThijs
  • Registratie: Maart 2004
  • Laatst online: 10:22
farlane schreef op vrijdag 07 april 2006 @ 11:11:
Hmm rare bug. Zou het zo niet weten maar heb je een mogelijkheid om het op een ander systeem te testen?
Op een ander systeem wil het ook niet werken.. Ik heb zelf nog gedubbelchecked op een 3de systeem, maar ook daar deed ie niets..
joopst schreef op vrijdag 07 april 2006 @ 11:48:
En als je het test zonder die proxysocket ? .. Als het dan wel werkt, dan weet je dat de fout bij de proxysocket zit ..
Lezen is een vak: Zoals ik in de laatste alinea al heb vermeld werkt het ook niet als ik ProxySocket weglaat.. Ik heb zowel gewerkt met de normale "Socket" class, als met TcpClient, waarvoor ik heel de basisclass heb moeten herschrijven..

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

volgens mij gebeurt dit, maar ik kan er volledig naast zitten
1) asynchone read begint
2) 1+ pakketten komt binnen en jouw code wordt uigevoerd
3) tijdens verwerking komt nog een pakket binnen
4) jij leest de hoeveelheid van die eerste pakketten uit
5) de Socket doet nix(?)
6) jij start nieuwe BeginReceive die niet getriggered wordt
7) timeout treedt op en connectie sluit.

Tis een gissing, en ze druist hier en daar in tegen alles, maar probeer eens binnen de EndReceive()
meer in te lezen dan wat er eerst kwam. (gebruik dus Socket.DataAvailable of hoe et ook noemt)

ASSUME makes an ASS out of U and ME


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
HIGHGuY schreef op vrijdag 07 april 2006 @ 21:04:
volgens mij gebeurt dit, maar ik kan er volledig naast zitten
1) asynchone read begint
2) 1+ pakketten komt binnen en jouw code wordt uigevoerd
3) tijdens verwerking komt nog een pakket binnen
4) jij leest de hoeveelheid van die eerste pakketten uit
5) de Socket doet nix(?)
6) jij start nieuwe BeginReceive die niet getriggered wordt
7) timeout treedt op en connectie sluit.

Tis een gissing, en ze druist hier en daar in tegen alles, maar probeer eens binnen de EndReceive()
meer in te lezen dan wat er eerst kwam. (gebruik dus Socket.DataAvailable of hoe et ook noemt)
Tijdens de endreceive wordt ook weer beginreceive aangeroepen ( als er geen exceptions optreden ), dus dat zou eigenlijk niet moeten kunnen

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.


  • CyberThijs
  • Registratie: Maart 2004
  • Laatst online: 10:22
farlane schreef op maandag 10 april 2006 @ 08:42:
[...]


Tijdens de endreceive wordt ook weer beginreceive aangeroepen ( als er geen exceptions optreden ), dus dat zou eigenlijk niet moeten kunnen
Feit is ook dat wanneer een packet pas enkele seconden later toekomt nadat hij is beginnen hangen, dat ik dat packet dan ook niet ontvang, terwijl ik dat door de stelling HIGHGuY dan weer wel zou moeten kunnen.. Daar ligt het dus ook al niet aan..

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 16-10 10:47
Ik ben nog redelijk nieuw met C# dus het kan zijn dat ik er naast zit. Maar zover ik kan opmaken uit je code maak je geen gebruik van threads om binnenkomende packets af te laten handelen. Mijn vraag is nu. Waarom niet?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
Wat je zou kunnen doen is 'back to basic' polling (eventueel in een testprojectje als het te ingewikkeld is om het in dit project te doen ), en kijken of paketten dan wel weer goed binnen komen. Dan stap voor stap je asynchrone structuur weer terug zetten en kijken op welk moment het mis gaat.
Mijn vraag is nu. Waarom niet?
Complexiteit kan een reden zijn om dat niet te doen. Iha als je het kunt redden zonder threads te gebruiken kun je het beter niet doen :)

[ Voor 27% gewijzigd door farlane op 11-04-2006 08:33 ]

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