partitionist
Erfahrenes Mitglied
Hallo Leute,
ich habe eine Art RPC Projekt (Konsole) erstellt, d.h. man kann im Netzwerk/LAN von einem Client Befehle zum Server senden, der diese dann ausführt. In dem Projekt sind mehrere System Tools in Form von *.exe Dateien wie z.B. kill.exe (Schließt Prozesse), info.exe (Ausgabe von System Infos), proc.exe (Ausgabe von Prozessen), user.exe, ...
Diese Tools und der Client/Server befinden sich im gleichen Ordner.
Beispiel:
Auf dem PC1 läuft der Client.
Auf dem PC2 läuft der Server.
Ablauf:
Jetzt baue ich eine Verbindung mit dem Client zum Server auf. Soabald dies geschehen ist, kann ich in der Konsole des Clients Befehle wie kill, info, proc,... übergeben/senden. Der Server startet mit system(BEFEHL) alle übegebenen Befehle die in dem gleichen Ordner sind.
Beispiel: Soabald der Befehl info übegeben wird, startet der Server die info.exe im gleichen Ordner und führt sie aus, und es erscheint beim Server die Ausgabe von info.
Problem:
Wie bekommt man die Ausgabe vom Server übers Netzwerk umgeleitet?
Also wie in dem obigen Beispiel mit info, die Ausgabe von info.exe möchte ich nur im Client sehen.
Hab mich hier im Forum umgeschaut und es gab ein ähnliches Thema aber keine Lösung: http://www.tutorials.de/forum/c-c/244182-cmd-steuern.html?highlight=pipes
Hier mein Client/Server
Client:
Server:
ich habe eine Art RPC Projekt (Konsole) erstellt, d.h. man kann im Netzwerk/LAN von einem Client Befehle zum Server senden, der diese dann ausführt. In dem Projekt sind mehrere System Tools in Form von *.exe Dateien wie z.B. kill.exe (Schließt Prozesse), info.exe (Ausgabe von System Infos), proc.exe (Ausgabe von Prozessen), user.exe, ...
Diese Tools und der Client/Server befinden sich im gleichen Ordner.
Beispiel:
Auf dem PC1 läuft der Client.
Auf dem PC2 läuft der Server.
Ablauf:
Jetzt baue ich eine Verbindung mit dem Client zum Server auf. Soabald dies geschehen ist, kann ich in der Konsole des Clients Befehle wie kill, info, proc,... übergeben/senden. Der Server startet mit system(BEFEHL) alle übegebenen Befehle die in dem gleichen Ordner sind.
Beispiel: Soabald der Befehl info übegeben wird, startet der Server die info.exe im gleichen Ordner und führt sie aus, und es erscheint beim Server die Ausgabe von info.
Problem:
Wie bekommt man die Ausgabe vom Server übers Netzwerk umgeleitet?
Also wie in dem obigen Beispiel mit info, die Ausgabe von info.exe möchte ich nur im Client sehen.
Hab mich hier im Forum umgeschaut und es gab ein ähnliches Thema aber keine Lösung: http://www.tutorials.de/forum/c-c/244182-cmd-steuern.html?highlight=pipes
Hier mein Client/Server
Client:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#include <conio.h>
#include <string>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <vector>
using namespace std;
#pragma comment(lib,"wsock32.lib")
// Startet Winsock und gibt einige Infos zur Version aus
// Starts winsock and dumps some infos about the version
int startWinsock()
{
int rc;
WSADATA wsaData;
rc=WSAStartup(MAKEWORD(2,0),&wsaData);
if(rc==SOCKET_ERROR)
{
printf("Error, exiting!\n");
return rc;
}
printf("System Status: %s\n",wsaData.szSystemStatus);
return 0;
}
// Sucht eine IP anhand eines Strings, der entweder die IP als String
// oder einen Hostname enthalten kann
long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr)
{
long rc;
unsigned long ip;
HOSTENT* he;
if(hostnameOrIp==NULL || addr==NULL)
return SOCKET_ERROR;
ip=inet_addr(hostnameOrIp);
if(ip!=INADDR_NONE)
{
addr->sin_addr.s_addr=ip;
return 0;
}
else
{
he=gethostbyname(hostnameOrIp);
if(he==NULL)
{
return SOCKET_ERROR;
}
else
{
memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
}
return 0;
}
}
int main(int argc, char* argv[])
{
if(argc > 2)
{
char* HOST = argv[1];
int PORT = atoi(argv[2]);
SOCKET s;
SOCKADDR_IN addr;
char c;
char buf[1024];
char inpBuf[1024];
int inpBufPos=0;
fd_set fdSetRead;
TIMEVAL timeout;
int rc;
// start winsock
rc=startWinsock();
if(rc==SOCKET_ERROR)
return 1;
// addr vorbereiten, hostname auflösen
// prepare addr, resolve hostname
memset(&addr,0,sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
rc=getAddrFromString(HOST, &addr);
if(rc==SOCKET_ERROR)
{
printf("Error: Cannot resolve Host %s\n", HOST);
return 1;
}
// socket erstellen
// create socket
s=socket(PF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET)
{
printf("Error, cannot create socket: %d\n",WSAGetLastError());
return 1;
}
// verbinden..
// connect..
printf("Connecting...\n");
rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
if(rc==SOCKET_ERROR)
{
printf("Error: connect failed: %d\n",WSAGetLastError());
return 1;
}
printf("\n");
string str; //Eingabe String
do
{
cout << "Eingabe:";
getline(cin, str);
if(str == "exit")
{
closesocket(s);
WSACleanup();
return 0;
}
else if(str == "close")
{
rc=send(s,str.c_str(),strlen(str.c_str()),0);
closesocket(s);
WSACleanup();
return 0;
}
//cout << "send->" << str << endl;
rc=send(s,str.c_str(),strlen(str.c_str()),0);
// fd_set und timeout vorbereiten
// prepare fd_set and timeout
FD_ZERO(&fdSetRead);
FD_SET(s,&fdSetRead);
timeout.tv_sec=0;
timeout.tv_usec=0;
// prüfen ob ein socket bereit ist, da timeout=0 kehrt die funktion
// sofort wieder zurück nach dem aufruf.
// achtung: das timeout auf 0 setzen oder als paremeter NULL mitgeben
// ist NICHT das gleiche. auf 0 gesetzt kehrt sofort zurück, während
// NULL blockt.
// check if any socket is ready (timeout=0, the function returns without delay)
while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0)
{
rc=recv(s,buf,1023,0);
// server hat die verbindung beendet ?
// server closed connection ?
if(rc==0)
{
printf("Server closed connection!\n");
return 1;
// fehler: beenden!
// error: abort!
} else if(rc==SOCKET_ERROR)
{
printf("Error: recv failed: %d\n",WSAGetLastError());
return 1;
}
// empfangene daten ausgeben
// print received data
buf[rc]='\0';
printf("%s\n",buf);
}
}while(rc!=SOCKET_ERROR);//Ende do-while
// aufräumen
// cleanup..
closesocket(s);
WSACleanup();
printf("Client shutdown, press any key to exit\n");
getch();
}
else
{
cout << "Client HOST PORT" << endl;
}
return 0;
}
Server:
Code:
// max. Anzahl Clients
// Max. number of clients
#define MAX_CLIENTS 100
// Der Standartwert für FD_SETSIZE ist 64, dieser kann aber verändert
// werden indem man FD_SETSIZE auf einen anderen Wert setzt bevor man
// winsock2.h includiert.
// FD_SETSIZE auf die max. Anzahl Clients setzten
#define FD_SETSIZE MAX_CLIENTS
// includes...
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#include <conio.h>
#include <string>
#include <iostream>
#include "convert.h"
#include "registry.h"
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib, "advapi32.lib")
using namespace std;
// Stellt eine Verbindung mit einem Client dar
// Represents a connection with a Client
struct Connection
{
Connection()
{
used=false;
socket=INVALID_SOCKET;
}
void set(SOCKET s, SOCKADDR_IN addr)
{
this->socket=s;
this->addr=addr;
this->used=true;
}
void erase()
{
this->used=false;
this->socket=INVALID_SOCKET;
}
bool used; // connection benutzt ? / connection slot used ?
SOCKET socket; // socket
SOCKADDR_IN addr; // client addr
};
// clients
Connection clients[MAX_CLIENTS];
// Sucht den nächsten freien Platz im clients Array
// -1 = kein platz frei
// Searches the next free slot in the clients array
// -1 = no free slot
int getFreeClientSlot()
{
for(int i=0;i<MAX_CLIENTS;i++)
{
if(clients[i].used==false)
return i;
}
return -1;
}
// Sendet eine Nachricht an alle Clients
// Send's a Message to all clients
int sendToAllClients(char* msg)
{
int rc,i;
for(i=0;i<MAX_CLIENTS;i++)
{
if(!clients[i].used)
continue;
rc=send(clients[i].socket,msg,strlen(msg),0);
if(rc==SOCKET_ERROR)
{
printf("Error: Sending to Client %d failed: %d\n",i,WSAGetLastError());
}
}
return 0;
}
// Startet Winsock und gibt einige Infos zur Version aus
// Starts winsock and dumps some infos about the version
int startWinsock()
{
int rc;
WSADATA wsaData;
rc=WSAStartup(MAKEWORD(2,0),&wsaData);
if(rc==SOCKET_ERROR) {
printf("Error, exiting!\n");
return rc;
}
printf("System Status: %s\n",wsaData.szSystemStatus);
return 0;
}
int main(int argc, char* argv[])
{
if(argc > 1)
{
//Startet auf dem übergebenem PORT
int PORT = atoi(argv[1]);
// SOCKET welcher neue Verbindungen annimmt
// SOCKET which accepts new connections
SOCKET acceptSocket;
SOCKADDR_IN addr;
int rc,addrsize=sizeof(SOCKADDR_IN);
unsigned int i,j;
// fd_set
fd_set fdSetRead;
// timout für select() / timeout for select()
timeval selectTimeout;
// temporär benutz für neue verbindungen
// temporary used for new connections
Connection newConnection;
// buffer
char buf[1024];
// clients array leeren / clear clients array
memset(clients,0x0,sizeof(Connection)*MAX_CLIENTS);
// start winsock
rc=startWinsock();
if(rc==SOCKET_ERROR)
return 1;
// socket erstellen / create socket
acceptSocket=socket(PF_INET,SOCK_STREAM,0);
if(acceptSocket==INVALID_SOCKET)
{
printf("Error, cannot create socket: %d\n",WSAGetLastError());
return 1;
}
// sockt an port 1234 binden / bind socket to port 1234
memset(&addr,0,sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=INADDR_ANY;
rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
if(rc==SOCKET_ERROR)
{
printf("Error, bind() failed: %d\n",WSAGetLastError());
return 1;
}
// auf verbindungen warten / listen for connections
rc=listen(acceptSocket,10);
if(rc==SOCKET_ERROR)
{
printf("Error,listen() failed: %d\n",WSAGetLastError());
return 1;
}
// The parameter readfds identifies the sockets that are to be checked for readability.
// If the socket is currently in the listen state, it will be marked as readable if an
// incoming connection request has been received such that an accept is guaranteed to
// complete without blocking.
while(1)
{
// fd_set leeren / clear fd_set
FD_ZERO(&fdSetRead);
// den socket welcher verbindungen annimmt hinzufügen
// add the SOCKET which accepts new connections
FD_SET(acceptSocket,&fdSetRead);
// alle clients hinzufügen
// add all clients
for(i=0;i<MAX_CLIENTS;i++)
{
if(clients[i].used)
FD_SET(clients[i].socket,&fdSetRead);
}
// warten bis irgend ein socket bereit ist, wenn timout NULL ist kehrt select()
// erst zurück wenn ein socket bereit ist, select() blockt also in diesem falle
// wait until any socket is ready (timeout = NULL, block until one socket is ready)
rc=select(0,&fdSetRead,NULL,NULL,NULL);
// abbrechen bei einem fehler
// break on error
if(rc<1)
break;
printf("select() returned %d ready sockets\n",rc);
for(i=0;i<fdSetRead.fd_count;i++)
{
// acceptSocket ?
if(fdSetRead.fd_array[i]==acceptSocket)
{
// verbindung annehmen / accept new connection
newConnection.socket=accept(acceptSocket,(SOCKADDR*)&newConnection.addr,&addrsize);
rc=getFreeClientSlot();
if(rc==-1)
{
printf("Cannot accept new clients\n");
continue;
}
// zu den clients hinzufügen
// add to clients
clients[rc]=newConnection;
clients[rc].used=true;
printf("New Client accepted from %s\n",inet_ntoa(newConnection.addr.sin_addr));
continue;
}
// ein client ?
// a client ?
for(j=0;j<MAX_CLIENTS;j++)
{
if(!clients[j].used)
continue;
if(clients[j].socket==fdSetRead.fd_array[i])
{
rc=recv(clients[j].socket,buf,1023,0);
buf[rc]='\0';
// rc==0 => client hat die verbindung beendet
// rc==0 => client closed connection
if(rc==0) {
printf("Client %d (%s): closed connection\n",j,inet_ntoa(clients[j].addr.sin_addr));
closesocket(clients[j].socket);
clients[j].erase();
continue;
// rc==SOCKET_ERROR => fehler, verbindung beenden!
// rc==SOCKET_ERROR => error, close connection!
}
else if(rc==SOCKET_ERROR)
{
printf("Client %d (%s): Error %d\n",j,inet_ntoa(clients[j].addr.sin_addr),WSAGetLastError());
printf("Client %d (%s): Server aborts connection\n",j,inet_ntoa(clients[j].addr.sin_addr));
closesocket(clients[j].socket);
clients[j].erase();
continue;
// daten empfangen und an alle clients senden
// receive data and send it to all clients
}
else
{
printf("Client %d (%s): received '%s' \n",j,inet_ntoa(clients[j].addr.sin_addr),buf);
//sendToAllClients(buf);
string command = buf;
int pos = command.find(' ');
int lang = command.length();
string task = command.substr(0,pos);
string para = command.substr(pos+1,lang);
if(task == "close")
{
//rc=send(clients[i].socket,msg,strlen(msg),0);
rc=send(clients[j].socket,task.c_str(),strlen(task.c_str()),0);
closesocket(acceptSocket);
WSACleanup();
}
else
{
string str;
str += '"';
str += reg.xmd_GetValue("bin");
str += "\\";
str += task;
str += '"';
str += " ";
str += para;
cout << "exec:" << str << endl;
system(str.c_str()); // <<--------- Hier werden die Befehle ausgeführt.
}
}
}
}
}
cout << "-----------------------------------" << endl;
}//Ende while
// aufräumen
// cleanup
closesocket(acceptSocket);
WSACleanup();
}
else
{
cout << "server PORT" << endl;
}
return 0;
}