tutorials.de Buch-Aktion 05/2012
Like Tree2Danke
  • 1 Beitrag von kickerxy123
  • 1 Beitrag von kickerxy123
ERLEDIGT
JA
ANTWORTEN
11
ZUGRIFFE
493
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    Hallo,

    ich bin noch ganz frisch mit der Visual C++ und Netzwerkprogrammierung. Deshalb muss ich jetzt hier um Rat fragen.
    Also ich habe ein Automationsgerät, welches über Netzwerk strings abfrägt and dann Aufgaben erledigt.
    Also zB Gerät erhält String "Do1" dann macht es ein bestimmtes Programm auf.
    Wenn ich eine Verbindung über Putty aufmache mit Telnet oder Raw, die Ip und den Port eingebe, dann funktioniert das auf wunderbar.
    --->ich gebe "Do1" ein --->Programm startet

    Jetzt wollte ich mir die ganze Sache selbst Programmieren und bin dabei über die Beispiele von http://www.c-worker.ch/tuts.php gestoßen.
    Diese funktionieren auch mit Server+ Client.
    Wenn ich das Clientprogramm allein laufen lasse und an mein Gerät connecte, kann iach zwar senden, aber es passiert nichts.
    hier der Code des Clientbeispiels:
    Code cpp:
    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    
    #pragma comment(lib, "Ws2_32.lib") 
     
    #include "stdafx.h"
     
    #include <windows.h>
    #include <stdio.h> 
     
     
    //Prototypen
    int startWinsock(void);
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr);
     
    int main(int argc, char** argv)
    {
      long rc;
      SOCKET s;
      SOCKADDR_IN addr;
      char buf[256];
     
      if(argc<2)
      {
        printf("Usage: sock <hostname oder ip des servers>\n");
        return 1;
      }
     
     
      // Winsock starten
      rc=startWinsock();
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
     
      // Socket erstellen
      s=socket(AF_INET,SOCK_STREAM,0);
      if(s==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
     
      // Verbinden
      memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
      addr.sin_family=AF_INET;
      addr.sin_port=htons(32001); // wir verwenden mal port 12345
      rc=getAddrFromString(argv[1],&addr);
      if(rc==SOCKET_ERROR)
      {
        printf("IP für %s konnte nicht aufgeloest werden\n", argv[1]);
        return 1;
      }
      else
      {
        printf("IP aufgeloest!\n");
      }
     
     
      rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Verbunden mit 127.0.0.1..\n");
      }
     
     
      // Daten austauschen
      while(rc!=SOCKET_ERROR)
      {
        printf("\nZeichenfolge eingeben [max 256]: ");
        gets(buf);
        send(s,buf,strlen(buf),0);
       // rc=recv(s,buf,256,0);
      //  if(rc==0)
        {
        //  printf("Server hat die Verbindung getrennt..\n");
         // break;
        }
        if(rc==SOCKET_ERROR)
        {
          printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
          break;
        }
        buf[rc]='\0';
        printf("\nServer antwortet: %s\n",buf);
      }
      closesocket(s);
      WSACleanup();
      return 0;
    }
     
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
     
     
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr)
     
    {
      long rc;
      unsigned long ip;
      HOSTENT* he;
     
     
      /* Parameter prüfen */
      if(hostnameOrIp==NULL || addr==NULL)
        return SOCKET_ERROR;
     
     
      /* eine IP in hostnameOrIp ? */
      ip=inet_addr(hostnameOrIp);
     
      /* bei einem fehler liefert inet_addr den Rückgabewert INADDR_NONE */
      if(ip!=INADDR_NONE)
      {
        addr->sin_addr.s_addr=ip;
        return 0;
      }
      else
      {
        /* Hostname in hostnameOrIp auflösen */
        he=gethostbyname(hostnameOrIp);
        if(he==NULL)
        {
          return SOCKET_ERROR;
        }
        else
        {
          /*die 4 Bytes der IP von he nach addr kopieren */
          memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
        }
        return 0;
     
      }
    }
     
    Könntet Ihr mir bitte ein paar Tipps geben warum das nicht funktioniert, und wo ich mich weiter einlesen kann?

    Mfg
    Chris
    Geändert von sheel (23.01.12 um 16:22 Uhr) Grund: Codetags
     

  2. #2
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Bitte nutze die Code-Tags für deinen Code.

    Ich vermute mal du müßtest den Befehl mit einem Zeilenendezeichen abschließen.

    Die Funktion gets liest eine Zeile bis zum \n ein, verwirft das \n aber. D.h. du müßtest noch ein \n an den String dranbasteln und dementsprechend auch übertragen.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  3. #3
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    Danke für die schnelle Antwort!

    Macht Putty denn eine Terminierung? Die Strings sende ich dort ohne.
    Ich habs jetzt mit \n , \r\n und \0 probiert, aber da passiert einfach nichts.
    Was macht denn Putty so viel anders?

    Gibt es vielleicht ein anderes Codebeispiel, bei dem man an einen Netzwerkpartner einen String sendet?
     

  4. #4
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Zitat Zitat von parthagas Beitrag anzeigen
    Danke für die schnelle Antwort!

    Macht Putty denn eine Terminierung? Die Strings sende ich dort ohne.
    Du drückst also nicht die Eingabetaste?
    Zitat Zitat von parthagas Beitrag anzeigen
    Ich habs jetzt mit \n , \r\n und \0 probiert, aber da passiert einfach nichts.
    Zeig deinen Code.
    Zitat Zitat von parthagas Beitrag anzeigen
    Was macht denn Putty so viel anders?
    Verwende wireshark und finde es heraus.

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  5. #5
    Eburneolus Eburneolus ist offline Mitglied
    Registriert seit
    Mar 2011
    Beiträge
    15
    Soweit ich weiss wird bei Telnet jedes Zeichen sofort nach der Eingabe zum verbundenen Endgerät geschickt. Wenn dein Client nun jedoch einen vollständigen Befehl erwartet und alle davor eingegangenen Daten verwirft kann dein Client nicht mehr als 1-zeichenlange Befehle interpretieren. Schreib einfach alle Daten die du bisher erhalten hast in einen Buffer und werte die Übertragung erst mit Übertragung von \r\n aus.
     

  6. #6
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    So, ich habe jetzt mit wireshark verglichen was passiert wenn ich "test" sende:

    Putty sendet:
    0000 00 50 c2 bf d0 20 8c 73 6e ab 1c 58 08 00 45 00 .P... .s n..X..E.
    0010 00 2c 05 7b 40 00 80 06 00 00 c0 a8 01 81 c0 a8 .,.{@... ........
    0020 01 c9 c6 e9 7d 01 bb 3e 0e 09 1c 3f 69 21 50 18 ....}..> ...?i!P.
    0030 40 e8 84 b9 00 00 74 65 73 74 @.....te st

    0000 00 50 c2 bf d0 20 8c 73 6e ab 1c 58 08 00 45 00 .P... .s n..X..E.
    0010 00 2a 05 77 40 00 80 06 00 00 c0 a8 01 81 c0 a8 .*.w@... ........
    0020 01 c9 c6 e9 7d 01 bb 3e 0e 07 1c 3f 69 21 50 18 ....}..> ...?i!P.
    0030 40 e8 84 b7 00 00 0d 0a @.......

    Ich sende nur:

    0000 00 50 c2 bf d0 20 8c 73 6e ab 1c 58 08 00 45 00 .P... .s n..X..E.
    0010 00 2c 05 38 40 00 80 06 00 00 c0 a8 01 81 c0 a8 .,.8@... ........
    0020 01 c9 c6 e8 7d 01 32 fc a3 04 5e fc 19 72 50 18 ....}.2. ..^..rP.
    0030 40 e8 84 b9 00 00 74 65 73 74 @.....te st


    Ich schätze mal das zweite, leere Packet von Putty ist die Terminierung? Das Problem ist, wenn ich \n oder \0 eingebe sedet er es einfach mit, also zb @.....te st\n

    Hier ist nochmal ein Codeausschnitt:
    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
    
    long rc;
      SOCKET s;
      SOCKADDR_IN addr;
      char buf[256];
     
      if(argc<2)
      {
        printf("Usage: sock <hostname oder ip des servers>\n");
        return 1;
      }
     
     
      // Winsock starten
      rc=startWinsock();
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
     
      // Socket erstellen
      s=socket(AF_INET,SOCK_STREAM,0);
      if(s==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
     
      // Verbinden
      memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
      addr.sin_family=AF_INET;
      addr.sin_port=htons(12345); // wir verwenden mal port 12345
      rc=getAddrFromString(argv[1],&addr);
      if(rc==SOCKET_ERROR)
      {
        printf("IP für %s konnte nicht aufgeloest werden\n", argv[1]);
        return 1;
      }
      else
      {
        printf("IP aufgeloest!\n");
      }
     
     
      rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Verbunden mit 192.168.1.1\n");
      }
     
     
      // Daten austauschen
      while(rc!=SOCKET_ERROR)
      {
        printf("\nZeichenfolge eingeben [max 256]: ");
        gets(buf);
        send(s,buf,(strlen(buf)+1),0);
      }
      closesocket(s);
      WSACleanup();
      return 0;
    }

    Wie kann ich die Eingabe Terminieren, ohne dass es gesendet wird?

    Grüße
    Chris
     

  7. #7
    kickerxy123 kickerxy123 ist offline Mitglied Gold
    Registriert seit
    Mar 2008
    Beiträge
    147
    Hallo,
    wie du schon richtig erkannt hast, sendet putty in dem zweiten Paket Terminierungszeichen.
    Am Ende des ersten Paketes hast du deine Nutznachricht (74 65 73 74 = test) und in dem zweiten Paket \0 \0 \r \n (0a = ascii-10 und 0d = ascii-13)

    versuch doch mal Folgendes:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     while(rc!=SOCKET_ERROR)
      {
        printf("\nZeichenfolge eingeben [max 256]: ");
        gets(buf);
        send(s,buf,(strlen(buf)+1),0);
        buf[0] = '\r';
        buf[1] = '\n';
        Sleep(300);
        send(s,buf, 2, 0);
      }


    Außerdem: wenn du \n in der Konsole eingibst, so wird das als Text - ein Backslash und ein n interpretiert und nicht als Steuerzeichen.

    Gruß,
    kickerxy
    Geändert von kickerxy123 (24.01.12 um 15:23 Uhr) Grund: 10 und 13 <-> \r \n verwechselt
    parthagas bedankt sich. 
    hilfreiche Antwort? Es gibt einen Danke-Button ;)
    Rettet das Internet!

  8. #8
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    Hi kickerxy. Erstmal danke, die Terminierung scheint nun zu funktionieren.
    Jetzt sehen beide gleich aus (Putty und meins).

    Trotzdem passiert bei meinem Programm noch nichts während bei Putty alles geht.

    Habe mir beide nochmal in wireshark angeschaut und gesehen, dass die Timings unterschiedlich sind.
    Bei Putty folgen beide Pakete direkt hintereinander mit Seq. 22 und 23. Der Zeitabstand ist ca. 40Microsekunden. Erst dann kommt das ACK von dem Gerät (zu dem ich verbinden will).

    Bei meiner Dosanwendung sind ein paar Millisekunden Abstand und das ACK kommt schon vor dem Paket mit der Terminierung. Die Seq. im wireshark hat einen großen Abstand.

    Bedeutet das nun, dass es zu langsam sendet? Die Sleep(300) hab ich bereits auskommentiert, trotzdem noch das selbe.
    Wie kann ich das zweite Paket sofort nach dem ersten senden?

    Oder bin ich hier komplett auf dem Holzweg und es liegt an etwas ganz anderem...

    MFG
     

  9. #9
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Bei dem Code von kickerxy wird zwischen test und dem Zeilentrenne
    noch ein \0 gesendet, das sollte weg.

    Also da, wo zu strlen 1 addiert wird, das +1 weg.
     
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  10. #10
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    hi sheel

    Das +1 habe ich bereits eintfernt. Der Code sieht nun so aus:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    while(rc!=SOCKET_ERROR)
      {
        printf("\nZeichenfolge eingeben [max 256]: ");
        gets(buf);
        send(s,buf,strlen(buf),0);
        buf[0] = '\r';
        buf[1] = '\n';
        send(s,buf, 2, 0);
      }

    Trotzdem kommt das ACK vom Zielobjekt bereits nach dem 1 Paket (nach dem 2 auch nochmal) und der Zeitabstand ist viel größer.
     

  11. #11
    kickerxy123 kickerxy123 ist offline Mitglied Gold
    Registriert seit
    Mar 2008
    Beiträge
    147
    Eventuell liegt das an den Socketoptionen (man mag mich korrigieren, wenn ich falsch liege).

    Füg mal

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    //...
    s=socket(AF_INET,SOCK_STREAM,0);
      if(s==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
    bool b = true;
    if(SOCKET_ERROR==setsockopt(s,IPPROTO_TCP,TCP_NODELAY, (char*)&b, sizeof(b)))
    {//...
    }
    //...

    ein und vergleiche nochmals den Sendeabstand beider Pakete.


    Gruß,
    kickerxy
    parthagas bedankt sich. 
    hilfreiche Antwort? Es gibt einen Danke-Button ;)
    Rettet das Internet!

  12. #12
    parthagas parthagas ist offline Rookie
    Registriert seit
    Jan 2012
    Beiträge
    6
    hey kickerxy,

    jetzt passen die Abstände und auch die Befehle funktionieren einwandfrei.

    vielen Dank!!
     

Ähnliche Themen

  1. Kompilieren von Putty
    Von NeMeSiS1987 im Forum C/C++
    Antworten: 0
    Letzter Beitrag: 28.10.09, 21:20
  2. UMTS und puTTy?
    Von cille im Forum Netzwerke
    Antworten: 2
    Letzter Beitrag: 10.06.09, 09:28
  3. CAsyncSocket - zwei Strings senden und einen empfangen
    Von Bastian N im Forum VisualStudio & MFC
    Antworten: 7
    Letzter Beitrag: 17.04.09, 10:00
  4. Putty Meldung
    Von newmem im Forum Netzwerke
    Antworten: 2
    Letzter Beitrag: 07.12.05, 11:24
  5. Einstieg SSH/ PUTTY ?
    Von BigDundee im Forum Linux & Unix
    Antworten: 6
    Letzter Beitrag: 09.03.05, 15:35