2Danke
ERLEDIGT
JA
JA
ANTWORTEN
11
11
ZUGRIFFE
493
493
EMPFEHLEN
-
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
ChrisGeändert von sheel (23.01.12 um 16:22 Uhr) Grund: Codetags
-
23.01.12 16:17 #2
- 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.
-
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?
-
23.01.12 17:15 #4
- Registriert seit
- Jun 2005
- Beiträge
- 8.168
If at first you don't succeed, try again. Then quit. No use being a damn fool about it.
-
23.01.12 17:45 #5
- 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.
-
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
-
24.01.12 15:19 #7
- 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ß,
kickerxyGeändert von kickerxy123 (24.01.12 um 15:23 Uhr) Grund: 10 und 13 <-> \r \n verwechselt
hilfreiche Antwort? Es gibt einen Danke-Button ;)
Rettet das Internet!
-
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
-
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, ...?
-
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.
-
25.01.12 12:51 #11
- 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ß,
kickerxyhilfreiche Antwort? Es gibt einen Danke-Button ;)
Rettet das Internet!
-
hey kickerxy,
jetzt passen die Abstände und auch die Befehle funktionieren einwandfrei.
vielen Dank!!
Ähnliche Themen
-
Kompilieren von Putty
Von NeMeSiS1987 im Forum C/C++Antworten: 0Letzter Beitrag: 28.10.09, 21:20 -
UMTS und puTTy?
Von cille im Forum NetzwerkeAntworten: 2Letzter Beitrag: 10.06.09, 09:28 -
CAsyncSocket - zwei Strings senden und einen empfangen
Von Bastian N im Forum VisualStudio & MFCAntworten: 7Letzter Beitrag: 17.04.09, 10:00 -
Putty Meldung
Von newmem im Forum NetzwerkeAntworten: 2Letzter Beitrag: 07.12.05, 11:24 -
Einstieg SSH/ PUTTY ?
Von BigDundee im Forum Linux & UnixAntworten: 6Letzter Beitrag: 09.03.05, 15:35





Zitieren


Login






