Server soll befehle ausführen
-
Hey folgendes ich hab mir einen client und einen server gebastelt mit dem code aus nem tut und nun hab ich zwei probleme 1. wie krieg ich hin das man beim client die ip des servers angibt und 2. soll zb wenn ich eine 1 sende der server den befehl unter 1 bei einem switch ausführen... beides funzt aber net
hier mal der client
#include <windows.h> #include <winsock2.h> #include <stdio.h> //Prototypen int startWinsock(void); char serverip[20]; int main() { long rc; SOCKET s; SOCKADDR_IN addr; char buf[256]; char ip; printf("Bitte Ziel-IP eingeben: "); scanf("%c",&ip); fflush(stdin); // 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 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); /* Was muss ich nun anstatt "127.0.0.1" eingeben.. hab ja schon ne abfrage der ip am anfang mit char*/ 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 %c \n",ip); } // Daten austauschen while(rc!=SOCKET_ERROR) { printf("\nBitte Befehl eingeben: "); 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); }und hier mal der server
#include <windows.h> #include <winsock2.h> #include <stdio.h> //Prototypen int startWinsock(void); int main() { long rc; SOCKET acceptSocket; SOCKET connectedSocket; SOCKADDR_IN addr; char buf[256]; char buf2[300]; // Winsock starten rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } // Socket erstellen acceptSocket=socket(AF_INET,SOCK_STREAM,0); if(acceptSocket==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Socket binden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(12345); addr.sin_addr.s_addr=ADDR_ANY; rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); if(rc==SOCKET_ERROR) { printf("Fehler: bind, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket an port 12345 gebunden\n"); } // In den listen Modus rc=listen(acceptSocket,10); if(rc==SOCKET_ERROR) { printf("Fehler: listen, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("acceptSocket ist im listen Modus....\n"); } // Verbindung annehmen connectedSocket=accept(acceptSocket,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { printf("Fehler: accept, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Neue Verbindung wurde akzeptiert!\n"); } // Daten austauschen while(rc!=SOCKET_ERROR) { rc=recv(connectedSocket,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("Client sendet: %s\n",buf); switch(buf) { case 8 : printf("\n PC wird heruntergefahren \n\n"); system("C:\\WINDOWS\\System32\\shutdown.exe -s -f -t 0 "); break; case 9 : printf("\n Programm wird beendet \n"); break; default: printf("\n Unbekannte Auswahl \n\n"); } sprintf(buf2,"Du mich auch %s",buf); rc=send(connectedSocket,buf2,strlen(buf2),0); } closesocket(acceptSocket); closesocket(connectedSocket); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }Ich benutz win xp und borland compiler... und beim kompilieren vom server krieg cih den fehler das ich integer beim switch brauch.. und wenn ich zb case 'asd' nehme um auf char zuzugreifen gibts noch mehr fehler...
ich denk mir die variable buf passt halt net aber wie und vorallem kann ich die passen umformatieren
ich hoffe ma ihr könnt mir helfen weil ich hab echt keinen plan was ich noch mahcen soll... hab schon seit stunden daran rumgebastelt aber noch will funzen
-
Mit
switchkannst du nur Integer-Werte vergleichen. Wenn du einzelne Zeichen (z. B. das erste Zeichen in deiner Zeichenkette), kannst duswitch (buf [0])verwenden. Außerdem vergleichst du mit Zahlen:'8'ist nicht das selbe wie8.Wenn du ganze Zeichenketten vergleichen willst:
if (!strcmp (buf, "8")) { ... } else if (!strcmp (buf, "9")) { ... } ...
-
devkid schrieb:
Mit
switchkannst du nur Integer-Werte vergleichen. Wenn du einzelne Zeichen (z. B. das erste Zeichen in deiner Zeichenkette), kannst duswitch (buf [0])verwenden. Außerdem vergleichst du mit Zahlen:'8'ist nicht das selbe wie8.Wenn du ganze Zeichenketten vergleichen willst:
if (!strcmp (buf, "8")) { ... } else if (!strcmp (buf, "9")) { ... } ...recv(..) empfängt nicht zwingend den ganzen String auf einmal. Dh. ev. ist der "String" nocht nicht null terminiert. Das würde strcmp(..) ganz schön durcheinander bringen.
Simon
-
hallo und ojemine
gleich am anfang des clients musst du ein array statt eines einzelnen zeichens deklarieren und zwar soviel um eine ip in dotted-schreibweise zu fassen. z.b.:
char ip[64]; // sollte reichen scanf("%s", ip); // string einlesenbei der printf-aktion gilt das selbe.
dann
fflush(stdin);ist verboten! wo haben die leute das immer her

die ip gibst du einfach mit
inet_addr(ip);an
da du nur eine ziffer sendest, kannst du auch direkt mit
buffer[0] == '1'arbeiten. ich würde allerdings auf der client-seite den befehl in ein z.b. int
umwandeln und den dann senden. desweiteren ist es nicht garantiert,
dass send alles mitnimmt was man reinstopft und recv auch nicht alles ausgibt.es kann durchaus sein, dass die hälfte noch unterwegs ist. du musst also in einer schleife solange senden bis alles weg ist und auch in einer schleife alles wieder empfangen, bis du das volle packet hast. dazu könnte man einfach die größe vorne weg schicken:
// SENDEN unsigned size = strlen(buf); int result = send(soc, reinterpret_cast<char *>(&size), sizeof(size), 0); // result testen unsigned rest = size; while (rest) { result = send(soc, reinterpret_cast<char *>(buf) + (size - rest), rest, 0); if (result == 0) // verbindung getrennt if (result == -1) // error rest -= result; } // EMPFANGEN: unsigned size; inr result = recv(soc, reinterpret_cast<char *>(&size), sizeof(size), 0); // result testen char *buf = new char[size]; // löschen nicht vergessen!! unsigned rest = size; while (rest) { result = recv(reinterpret_cast<char *>(buf) + (size - rest), rest, 0); if (result == 0) // verbindung getrennt if (result == -1) // error rest -= result; }allerding ist es unwahrscheinlich, dass das netzwerk ein 2 Byte Packet zerlegt.
desweiteren sendet windows immer alles oder nichts, weshalb man sich die schleife sparen kann. ist jedoch sonst nicht portabel :pbtw: falsches forum

-
ok danke für die antowrten und den support soweit... ich werd des morgen mal soweit probiern umzusetzen
der string wir doch hiermit null-terminiert oder hab ich da was falsch verstanden
buf[rc]='\0'; printf("Client sendet: %s\n",buf);ach und
fflush(stdin);hab ich aus em c/c++ tutorial von galileo computing oder so
und wie kann ich mit
send(s,buf,strlen(buf),0);einen int wert senden
buf muss doch char seinsry für die noob fragen aber ich hab halt schon lang nixmehr mit c/c++ gemacht und war eh nie viel weiter wwie die basics, die ich halt noch halbwegs so drauf hab

-
buf muss doch char sein
Nein, buf muss const char* sein (dein array wird in einen solchen pointer "konvertiert".). Du kannst auf alles sinnige und unsinnige mit buf als const char* zeigen und damit versenden.
Edit:
Bsp:
const char* buf = reinterpret_cast<const char*>(&a);
const size_t len = sizeof(a);
int ret = send(s, buf, len, 0);Simon
-
ich hab jetz ma alles soweit umgesetzt und jetzt funktioniert es endlich nochmals vielen dank an euch
-
so jungs jetz hab ich nur noch ein problem und zwar wird der server auch beendet wenn der client geschlossen wird und des liegt ja daran
while(rc!=SOCKET_ERROR) { rc=recv(connectedSocket,buf,256,0); if(rc==0) { printf("Server hat die Verbindung getrennt..\n"); break; }und wenn ich folgendes mach funzt es net un der server spinnt
while(rc!=SOCKET_ERROR) { rc=recv(connectedSocket,buf,256,0); if(rc==0) { rc=listen(acceptSocket,10); if(rc==SOCKET_ERROR) { printf("Fehler: listen, fehler code: %d\n",WSAGetLastError()); return 1; } // Verbindung annehmen connectedSocket=accept(acceptSocket,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { printf("Fehler: accept, fehler code: %d\n",WSAGetLastError()); return 1; } }kann man irgiendwie machen das der wieder vor der while schleifen aufs listen springt
-
ja, nimm listen raus aus while.
Simon
-
sry aber da haste wohl was falsch verstanden des listen is ja eigtl net drin in while ich habs halt mal reingemacht um zu probiern ob der server so nach einem disconnect vom client wieder auf neue verbindungen wartet und das richtige listen und so kommt vor der while nun weiß ich aber net wie ich machen soll das wenn der cleint beendet wird der der server anstatt zu beenden aus der while rausgeht und wieder nach oben zum listen springt...
goto geht ja nur zb in nem switch wenn ich des richtig verstanden hab also kann ich damit ja net arbeiten
-
Nein,
listenwird nur einmal aufgerufen, nicht vor jedemaccept.Normalerweise sollte so eine Schleife in etwa so aussehen (Pseudo-Code):
while (true) { new_socket = accept (s, NULL, 0); if (new_socket < 0) continue; // Kommunizieren rc = recv (s, buf, len, 0); if (rc < 0) continue; // ... }Bei jedem continue springt er dann wieder zum Anfang der Schleife und wartet auf eine neue Verbindung.
Wenn du richtig gut bist (
) kannst du jedes mal, wenn eine Verbindung ankommt, einen eigenen Thread startet, so dass du mehrere Clients verarbeiten kannst.
-
if (rc < 0) { // fehler } else if (rc == 0) { // verbindung von gegenstelle geschlossen } else { // daten bekommen... }Nur als Anmekrung...