Socket sendet anstatt auf Daten zu warten



  • Hallo zusammen,

    ich möchte zwei Anwendungen über einen Socket miteinander verbinden. Die eine Anwendung (Server) ist in C++ geschrieben, die Andere in C# (Client).
    Es ist definiert, dass der Socket-Client immer ein Kommando an den Server schickt und auf eine Antwort von diesem wartet.
    Dafür habe ich auf der Client-Seite folgenden Minimalcode implementiert:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    
    namespace SocketTest
    {
       public partial class Form1 : Form
       {
          public Form1()
          {
             InitializeComponent();
          }
    
          private void Form1_Load(object sender, EventArgs e)
          {
             m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             try
             {
                m_Socket.ReceiveTimeout = -1;
                m_Socket.SendTimeout = -1;
                m_Socket.Blocking = true;
                m_Socket.Connect("127.0.0.1", 50002);
             }
             catch (SocketException ex)
             {
                // this exception is thrown, if no socket server is available -> print error code
                System.Console.WriteLine(ex.ErrorCode);
             }
             catch (ObjectDisposedException ex)
             {
                // the socket was closed -> print message on console
                System.Console.WriteLine(ex.Message);
                // return false
             }
             byte[] buffer = { 0x00 };
             byte[] response = new byte[100];
             SendAndReceive(buffer, ref response);
             byte[] buffer2 = { 0x07, 0x00, 0x00, 0x00, 0x00 };
             SendAndReceive(buffer2, ref response);
             byte[] buffer3 = { 0x02 };
             SendAndReceive(buffer3, ref response);
          }
    
          private void SendAndReceive(byte[] cmd, ref byte[] response)
          {
             m_Socket.Send(cmd);
             m_Socket.Receive(response);
          }
    
          private Socket m_Socket;
       }
    }
    

    Habe mit einem Socket-Sniffer mitgeschnitten, was an Telegrammen auf dem Socket übertragen wird.
    Im Einzelschritt schaut das Ganze richtig aus, da kommen folgende Telegramme (C ist der Client, S ist der Server):
    C->S: 0x00
    S->C: 0x00
    C->S: 0x07 0x00 0x00 0x00 0x00
    S->C: 0x00 0x00
    C->S: 0x02
    S->C: 0x00

    Wenn ich das Ganze jetzt aber ohne Breakpoint - sprich im laufenden Betrieb - laufen lasse und mir die Telegramme anschaue habe ich folgenden zeitlichen Ablauf:
    C->S: 0x00
    S->C: 0x00
    C->S: 0x07 0x00 0x00 0x00 0x00
    C->S: 0x02
    S->C: 0x00

    S->C: 0x00 0x00

    Sprich der Client wartet nicht auf die Antwort auf das zweite Telegramm, sondern sendet sofort das Nächste. Wie kann das bitteschön sein? Und was kann ich dagegen tun?
    Das Problem ist, dass ich im eigentlichen Programm das gleiche Phänomen habe und es dort zu massiven Problemen kommt, wenn sich Telegramme gegenseitig überholen.

    Danke vorab für jede Hilfe und viele Grüße



  • Hi,

    also wenn das ganze im Debugger Modus per Einzelschritt klappt, denke ich das es nicht an der Übetragung sondern an der Anwendung liegt. Denke das da wohl das Programm oder Windows nicht in der Lage ist die korrekte Reihenfolge einzubehalten.

    Evt. würde es klappen wenn du das Senden der Daten manuell verzögern würdest.
    Nur so ein Gedanke von mir.

    Gruß
    Jeg



  • Reine Vermutung, aber eventuell liegt es am Nagle-Algorythmus.

    Versuch mal NoDelay = false zu setzen, damit schaltest Du Nagle explizit aus (default ist an)



  • Glaube mittlerweile auch, dass es an dem Tool liegt (SocketWorkbench).
    Die konkateniert scheinbar auch teilweise Telegramme, die auf dem Socket definitiv nacheinander übertragen werden zu einem Telegramm...

    Das deaktivieren des Nagle-Algorithmuses hat auf jeden Fall keine Änderung gebracht...

    Trotzdem danke und viele Grüße



  • bei TCP werden keine 'Telegramme' versendet.



  • Ampfing schrieb:

    Die konkateniert scheinbar auch teilweise Telegramme, die auf dem Socket definitiv nacheinander übertragen werden zu einem Telegramm...

    Das ist aber genau das, was der Nagle-Algo macht...



  • @sock_stream: Okay, ich nenne sie nicht Telegramme, sondern Pakete. Für mich sind es eben einfach Daten.

    @loks: Das Problem in meiner Applikation war ein ganz anderes. Die Pakete haben sich nicht gegenseitig überholt, wie ich ursprünglich gedacht hatte - eben weil es in dem Sniffer-Tool so dargestellt wurde. War tatsächlich ein Problem, dass die Serverapplikation zweimal in den Socket geschrieben hat bis der Client einmal gelesen hatte (und der Client damit zwei Pakete auf einmal lesen bekommt). Nachdem ich das herausgefunden hatte habe ich den Client etwas überarbeitet, so dass er damit jetzt auch umgehen kann.

    Danke für die Hilfe und viele Grüße


Log in to reply