Toon posts:

[.NET] Socket stuurt geen data in loop?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Over een socket ontvang ik berichten (commandos) van een client. Deze berichten worden afgehandeld door de server en de server stuurt naar de client weer een bericht terug. Zo onstaat er communicatie zoals dat bijvoorbeeld gebeurd bij het SMTP protocol.

In de code hieronder zie je dat de server een bericht stuurt via de streamwriter
naar de client waarin staat "100 SERVER ..etc.. ". Dit is voordat loop gestart wordt waarin de berichten die van de client komen, geevalueerd worden door een aparte functie die een string retourneerd. Alle berichten die ik voor de loop laat sturen komen bij de cient (op dit moment een VB6 test app) aan, alle berichten die in de loop gestuurd worden, lijken niet verstuurd te worden.
Ook de Consolse.Writeline()'s in de loop worden pas getoond zodra de client disconnect en de server dus uit de loop gaat. Wat doe ik verkeerd? :?

Overigens heb ik een hoop overbodige zut uit de code gehaald.

code:
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
82
83
    public class Processor
    {
        private Socket _socket;
        private bool _quitRequested = false;
        private StreamWriter _outputStream;
        private int ProcessorStatus;
        private UserAccount _Account;

        /// <summary>
        /// Initializes object for given socket.
        /// </summary>
        /// <param name="socket">Socket with established connection</param>
        public SMTPProcessor(Socket socket, string MailFolder)
        {
            _socket = socket;
            ProcessorStatus = 0;
        }

        /// <summary>Starts communication with client.</summary>
        public void Process()
        {
            string clientMessage = string.Empty;
            string serverMessage = string.Empty;

            NetworkStream networkStream = new NetworkStream(_socket);
            StreamReader streamReader = new StreamReader(networkStream);
            StreamWriter streamWriter = new StreamWriter(networkStream);

            try
            {
                // All writes will be done immediately and not cached:
                streamWriter.AutoFlush = true;

                // Send welcome message first:
                string welcome = "100 SERVER " + 
                System.Environment.MachineName + " READY AT " +
                        DateTime.Now.ToString() + ". PLEASE SEND LOGIN.";

                streamWriter.WriteLine(welcome);

                //status of processor is waiting for logon data
                ProcessorStatus = 1;

                // Start loop and handle commands:
                while (!_quitRequested)
                {
                    clientMessage = streamReader.ReadLine();
                    serverMessage = EvaluateCommand(clientMessage);
                    
                    if (clientMessage != "") {
                        Console.WriteLine("clientMessage: " + 
                        clientMessage);
                    }

                    if (serverMessage != "") {
                        Console.WriteLine("serverMessage: " + 
                        serverMessage);
                        streamWriter.WriteLine(serverMessage);
                    }
                    
                }
            }
            catch (Exception ex)
            {
                Logfile log = new Logfile();
                log.AddEvent("An Exception occured: " + ex.ToString());
                log.Close();
            }
            finally
            {
                streamWriter.Close();
                streamReader.Close();
                networkStream.Close();
                _socket.Close();
                _outputStream.Close();
                
                Logfile log = new Logfile();
                log.AddEvent("Server closed connection");
                log.Close();
            }
        }

    }

[ Voor 4% gewijzigd door Verwijderd op 15-12-2004 10:25 ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Komt hij de ReadLine wel door dan? Heb je alles al is gestept met de debugger? Je krijgt geen exception?

Ik zou trouwens ook in NetworkStream, StreamWriter en StreamReader even in je try block zetten en in de finally block ook controleren of ze niet null zijn.

[ Voor 44% gewijzigd door pjvandesande op 15-12-2004 10:33 ]


Verwijderd

Topicstarter
De readline komt door, deze wordt geparsed door de EvaluateCommand() method.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Als je je code doorstept, waar blijft hij dan hangen? Blijft hij hangen bij het ontvangen van de client data en je weet ook 100% zeker dat de client de data ook naar die socket stuurd?

Verwijderd

Topicstarter
Zolang de client geconnect blijft, wordt alleen het volgende getoond in de console:

15-12-2004 10:45:26 - Server Ready - Listening for new connections on 10.1.1.4..
15-12-2004 10:45:26 - Server started.
15-12-2004 10:45:30 - Client connected: 10.1.1.4:4162



Als de client dan disconnect, dan verschijnt ook het verstuurde en ontvangen bericht in de Console:

15-12-2004 11:16:21 - Server Ready - Listening for new connections on 10.1.1.4..
15-12-2004 11:16:21 - SMF server started.
15-12-2004 11:16:28 - Client connected: 10.1.1.4:4163
15-12-2004 11:16:38 - clientMessage: LOGN BETA1, PASS
15-12-2004 11:16:38 - serverMessage: 220 LOGIN FAILED
15-12-2004 11:16:38 - SMF-server closed connection


"220 LOGIN FAILED" wordt geretourneerd door de EvaluateCommand() method.
Als log.AddEvent wordt aangeroepen, dan wordt de string die wordt meegestuurd, ook naar de console geschreven met een datetime ervoor.

[ Voor 17% gewijzigd door Verwijderd op 15-12-2004 11:30 . Reden: ik heb de code verandert waardoor nu alles via log.Addevent wordt geschreven, is wellicht wat duidelijker. ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Dan is toch gewoon je login niet correct.

Verwijderd

Topicstarter
Sorry, mijn verhaal is niet duidelijk.
De serverMessage "220 LOGIN FAILED" komt nooit aan bij de client.
Zoals je ziet zit er 10 seconden tussen de volgende akties:

15-12-2004 11:16:28 - Client connected: 10.1.1.4:4163
15-12-2004 11:16:38 - clientMessage: LOGN BETA1, PASS

Dit komt, omdat ik de client app 10 seconden heb laten open staan voordat ik hem sloot.
Pas als ik de client app sluit, lijkt hij verder te gaan? Als ik 2 minuten wacht voordat ik de client app sluit, dan is de tijd tussen deze twee aktief 2 minuten. Het vreemde is dat het bericht "LOGN BETA1, PASS" direct door de client verstuurd wordt onload.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Drop is een stukje code van de Client als je wilt. Want pas als je de client app sluit stuurd hij de message?

Als je een break zet bij het OnLoad event, dan breakt hij wel gelijk en word het wel verzonden?

[ Voor 32% gewijzigd door pjvandesande op 15-12-2004 11:44 ]


Verwijderd

Topicstarter
Ik ga even een stukje client code ophalen, duurt even 20 minuten.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Verwijderd schreef op woensdag 15 december 2004 @ 12:07:
Ik ga even een stukje client code ophalen, duurt even 20 minuten.
Prima, er zijn overigens best veel SMTP components voor .NET waaronder ook een aantal gratis. Ik heb er zelf hier 1 gehad die werkte met events. Heerlijk om te implementeren zou alleen helaas niet meer weten hoe hij heet. Misschien dat dat nog een oplossing is, scheelt een hoop kostbare ontwikkel tijd.

Op planetsourcecode en/of codeproject zal ook nog wel een hoop staan. Maar, ik kan het goed begrijpen als je dit niet wilt gebruiken, maar ik wou het toch even laten vallen. :Y)

Verwijderd

Topicstarter
Het is geen SMTP procotol wat ik implementeer maar wellicht is het wel een idee om zo'n SMTP component als codebase te gebruiken. Aan de andere kant, ik ben nu zo ver.. afgezien van deze bug.

Hieronder staat de code van mijn bijzonder simpel opgezetten VB6 test programma.

code:
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
Option Explicit

Private Sub Form_Load()
  Call Winsock1.Connect("10.1.1.4", 25)
End Sub


Private Sub Winsock1_Close()
  List1.AddItem "Connection is closed"
End Sub


Private Sub Winsock1_Connect()
  List1.AddItem "Connected to server."
End Sub


Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  
  Dim strData As String
  Call Winsock1.GetData(strData)
  
  List1.AddItem "Received data: " & strData
  
  'send command to smf-server
  List1.AddItem "sending login now"
  Call Winsock1.SendData("LOGN myUserName, myPassword")

End Sub


Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
  List1.AddItem "Winsock_error: " & Description
End Sub


Private Sub Winsock1_SendComplete()
  List1.AddItem "Data is send"
End Sub

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Als je een breakje zet bij Call Winsock1.SendData("LOGN myUserName, myPassword") en even kijkt of deze wel gelijk word aangeroepen.

Je hoeft de data toch niet te flushen of na het zenden met het winsock component die je gebruikt?

Ik denk dat je er met wat creatief debug werk wel uit moet komen. Na de connect ontvange je gelijk data en word het DataArival event ook getriggerd, ik zie namelijk niet zo een fout in de source zelf.

Verwijderd

Topicstarter
De ouput in de list in de VB6 test app is als volgt:

-------------------------------
Connected to server.
Received data: 100 Server ...etc
Sending login now
Data is send.
-------------------------------

Zonder onderbrekingen binnen 1 sec. op scherm zichtbaar.
Begrijp er niets van.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Je vraagt een ReadLine op in de socket stream met de StreamReader, probeer is Read ipv ReadLine. Want je stuurt volgens mij geen nieuwe line, of eindigt je bericht wel op "\r\n"?

Verwijderd

Topicstarter
Sorry die "\r\n" moet je me even uitleggen als je wil. :)

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Met de ReadLine method, lees je een lijn is zeg maar, dus een string zoiets als: "Ik ben een bericht", maar de moet eindigen met een 'NewLine' indicatie, anders returned die method nog niet. Hij wacht dus op een NewLine indicatie, in C# is dat '\n' en in VB Crlf ofzo dacht ik. Probeer het is met de Read Method ipv ReadLine. Dit is denk ik de oplossing. Je kan ook in je VB client een string sturen met aan het einde zo'n Crlf, NewLine indicatie.

Verwijderd

Topicstarter
Het werkt! :)
vbNewline toevoegen aan het bericht wat verstuurd wordt vanuit de VB6 client, was inderdaad de oplossing.
Bedankt voor je hulp Questa!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 18-05 09:50

pjvandesande

GC.Collect(head);

Geen probleem!

Misschien is het ook nog handig om een Receive Timeout in te bouwen. Dit kan met de socket.Receive(..); method. Hiermee word de standaart Timeout gebruikt, maar deze kun je ook aanpassen.

Heel veel succes verder :)

Verwijderd

Topicstarter
Ok, zal het onthouden, thnx.
Pagina: 1