Kommunikationsprotokoll



  • Hallo,

    ich habe inzwischen schon recht gute Erfahrungen mit Winsock gemacht und würde mich gerne ein wenig weiterentwickeln. Dazu wollte ich ein kleines Protokoll erstellen.

    Folgendes habe ich dazu ausprobiert und es scheint auch korrekt zu klappen:

    #include <iostream>
    #include <sstream>
    #include <string>
    
    class Data
    {
    private:
    	unsigned int dataLen;
    	unsigned int dataCode;
    	std::string data;
    
    public:
    	Data( unsigned int dataCode, 
    		  const std::string& data )
    	{
    		this->dataCode = dataCode;
    		this->data = data;
    
    		this->dataLen = this->data.length();
    	}
    
    	const std::string str()
    	{
    		std::stringstream result;
    
    		result	<< "\x15\x11"
    				<< dataLen	<< "\x10"
    				<< dataCode << "\x10"
    				<< data
    				<< "\x90";
    
    		return result.str();
    	}
    };
    
    void parse(const std::string& input);
    
    int main()
    {
    	for (;;)
    	{
    		std::string temp;
    		std::cout << "\nData: ";
    		std::getline(std::cin, temp);
    		Data test(100, temp);
    
    		std::cout << test.str() << std::endl;
    		parse(test.str());
    	}
    	return 0;
    }
    
    void parse(const std::string& input)
    {
    	unsigned int pos = 2;
    	unsigned int len = 0;
    
    	if (input[0] == '\x15' && input[1] == '\x11')
    	{
    		std::cout << "Found protocol." << std::endl;
    
    		for (unsigned int i = 1; i <= 3; ++i)
    		{
    			std::cout << "[" << i << "]\t";
    
    			if (i != 3)
    			{
    				std::string strLen;
    				while (input[pos] != '\x10')
    				{
    					if (i == 1)
    					{
    						strLen += input[pos];
    					}
    					putchar(input[pos]);
    					++pos;
    				}
    
    				if (i == 1)
    				{
    					len = atoi(strLen.c_str());
    				}
    			}
    			else
    			{
    				for (int i = 0; i < len; ++i)
    				{
    					putchar(input[pos]);
    					++pos;
    				}
    			}
    
    			putchar('\n');
    
    			if (input[pos] == '\x10')
    			{
    				pos++;
    			}
    		}
    
    		if (input[pos] == '\x90')
    		{
    			std::cout << "Protocol end." << std::endl;
    		}
    	}
    }
    

    Jetzt meine Frage: Ist das die richtige Vorgehensweise? Wie sieht es mit Portabilität aus? Und wie setze ich das nun konkret bei einer Server-Client-Verbindung ein?

    Ich hoffe ihr könnt mir weiterhelfen 🙂

    Vielen Dank im Voraus,
    Porty

    PS: Ich würde mich auch sehr über Verbesserungsvorschläge im Bezug auf meinen Programmierstil, etc. freuen 🙂



  • Porty schrieb:

    Jetzt meine Frage: Ist das die richtige Vorgehensweise?

    nein, man schreibt erst eine spezifikation. muss ja nicht gleich so fett wie ein RFC werden, aber jeder muss verstehen können, wie das protokol funzt.

    Porty schrieb:

    Wie sieht es mit Portabilität aus?

    schlecht. mach sowas besser in reinem ansi-C, dann ist der code maximal portabel.

    🙂



  • result    << "\x15\x11"
              << dataLen    << "\x10"
              << dataCode << "\x10"
              << data
              << "\x90";
    

    "Spezifikation":
    Die Nachricht beginnt mit den Zeichen: \x15\x11

    Anschließend kommt eine Zahl, welche die Länge der Daten angibt. Das Ende wird durch ein \x10 terminiert.

    Anschließend folgt ein Statuscode. Das Ende wird duch ein \x10 terminiert.

    Schlussendlich kommt die eigentliche Textnachricht. Die Anzahl der Zeichen sollte dataCode entsprechen.

    Das Ende der Nachricht wird durch \x90 gekennzeichnet.
    Ende.

    Ich brauche noch Tipps zum eigentlichen Protokoll und der Umsetzung des Protokolls 🙂

    Hat da jemand Erfahrungen? 🙂 🙂 🙂

    Viele Grüße,
    Porty



  • *push*

    Ist mir sehr wichtig!



  • Ich würde noch eine Protokollversion und evtl. noch eine Inhaltskennzeichnung mit aufnehmen. Mit dieser Kennzeichnung kannst du dann falls zukünftig nötig, auch andere Daten als Text übertragen.



  • Diese Endterminierungen erscheinen mir irgendwie redundant, das Zeichen kann man sich auch sparen.
    Die Länge der Daten haste ja in deinem dataLen attribut.


Anmelden zum Antworten