PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wichtig Daemon, Linux, Webserver...


Matrix316
2004-01-06, 19:26:20
Wir sollen jetzt unter Linux einen Webserver als Daemon programmieren...schön und gut, aber nix lässt sich kompilieren mit gcc...

Einmal gibts den Daemon:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>

int daemonisieren()
{
pid_t pid;

if ((pid = fork())<0)
return -1;
else if (pit !=0)
exit(0); //Elternprozess beendet sich

/*Ab hier Kindprozess*/

setsid(); //Kind wird Sessionführer

chdir("/"); //ins Root Directory wechseln

umask (0); //Dateikreierungsmaske loeschen

return 0;
}

int main()
{
if (daemonisieren() !=0)
{
openlog(LOG_PID);
syslog("FEHLER: Daemonisierung nicht moeglich.\n");
closelog();
return -1;
}

openlog(LOG_PID);
syslog("...hallo ich bin jetzt ein Daemon...\n")
closelog();

sleep(20);
//webserver(port80)

openlog(LOG_PID);
syslog("...Deamon has left the building...\n")
closelog();

return -1;
}



Da gibts schonmal 5000 Fehlermeldungen:


daemon.cpp: In function `int daemonisieren()':
daemon.cpp:10: `fork' undeclared (first use this function)
daemon.cpp:10: (Each undeclared identifier is reported only once for each
function it appears in.)
daemon.cpp:12: `pit' undeclared (first use this function)
daemon.cpp:13: `exit' undeclared (first use this function)
daemon.cpp:17: `setsid' undeclared (first use this function)
daemon.cpp:19: `chdir' undeclared (first use this function)
daemon.cpp: In function `int main()':
daemon.cpp:30: invalid conversion from `int' to `const char*'
/usr/include/sys/syslog.h:176: too few arguments to function `void
openlog(const char*, int, int)'
daemon.cpp:30: at this point in file
daemon.cpp:31: invalid conversion from `const char*' to `int'
/usr/include/sys/syslog.h:183: too few arguments to function `void syslog(int,
const char*, ...)'
daemon.cpp:31: at this point in file
daemon.cpp:36: invalid conversion from `int' to `const char*'
/usr/include/sys/syslog.h:176: too few arguments to function `void
openlog(const char*, int, int)'
daemon.cpp:36: at this point in file
daemon.cpp:37: invalid conversion from `const char*' to `int'
/usr/include/sys/syslog.h:183: too few arguments to function `void syslog(int,
const char*, ...)'
daemon.cpp:37: at this point in file
daemon.cpp:38: parse error before `(' token
daemon.cpp:40: `sleep' undeclared (first use this function)
daemon.cpp:43: invalid conversion from `int' to `const char*'
/usr/include/sys/syslog.h:176: too few arguments to function `void
openlog(const char*, int, int)'
daemon.cpp:43: at this point in file
daemon.cpp:44: invalid conversion from `const char*' to `int'
/usr/include/sys/syslog.h:183: too few arguments to function `void syslog(int,
const char*, ...)'
daemon.cpp:44: at this point in file
daemon.cpp:45: parse error before `(' token
daemon.cpp:49:1: warning: no newline at end of file


Obwohl es hieß, dass das Ding so lauffähig wäre...

Zum Webserver komm ich noch...

Magnum
2004-01-06, 20:05:49
OK, fangen wir mal an:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
#include <stdio.h> //sollte eigentlich immer dabei sein, man weiss nie, ob mans braucht
#include <unistd.h> //dito - hier müsste auch fork drin sein!

int daemonisieren()
{
pid_t pid;

if ((pid = fork())<0)
return -1;
else if (pid !=0) // pid statt pit
exit(0); //Elternprozess beendet sich

/*Ab hier Kindprozess*/

setsid(); //Kind wird Sessionführer

chdir("/"); //ins Root Directory wechseln

umask (0); //Dateikreierungsmaske loeschen

return 0;
}

int main()
{
if (daemonisieren() !=0)
{
openlog(LOG_PID);
syslog("FEHLER: Daemonisierung nicht moeglich.\n");
closelog();
return -1;
}

openlog(LOG_PID);
syslog("...hallo ich bin jetzt ein Daemon...\n")
closelog();

sleep(20);
//webserver(port80)

openlog(LOG_PID);
syslog("...Deamon has left the building...\n")
closelog();

return -1;
}



Änder mal das, das ich fett gemacht habe, danach sehen wir weiter!

Nagilum
2004-01-06, 20:18:57
Fehlende Header:
Wenn der Compiler meldet, dass er bestimmte Standardfunktionen wie chdir(), fork() usw. nicht kennt, dann hast du den entsprechenden Header nicht inkludiert. Ruf einfach "man chdir", "man fork" usw. in der Konsole auf. Dort sollte stehen welche Header man dafür benötigt. Ein "grep" im /usr/include Verzeichnis hilft zur Not auch weiter.

Zeile 12:
Wohl ein Tippfehler.

openlog()
Ich kenn openlog() nur mit 3 Parametern? Name, Optionen und Typ sollte man der Funktion übergeben. Du übergibst aber nur ein Flag für die Optionen (LOG_PID)? Probier mal sowas:

openlog("MeinDaemonchen", LOG_PID, LOG_DAEMON);

syslog()
Ähnlich wie openlog(). Schau dir mal die Manpage an. Wahrscheinlich musst du zusätzlich zur Meldung noch die Priorität angeben.

Zeile 44
Wieder Tippfehler am Ende der Zeile...

Rückgabewert von main()
Entweder 0 (EXIT_SUCCESS) oder 1 (EXIT_FAILURE).



Vergiss das mit openlog(). Bei dir reicht ja anscheinend ein Parameter. Ich brauch hier 3.

Matrix316
2004-01-06, 21:05:25
Also ich hab mal nachgesehen und openlog und closelog sind anscheinend nur optional.

Aber wie ganau würde syslog(... aussehen?

So?

syslog(LOG_DAEMON|LOG_INFO,printf("..."));
[code]

Und wenn da im man file steht:


void syslog( int priority, char *format, ...)

[...]

syslog() erzeugt eine Log-Nachricht, die vom syslogd(8) verarbeitet
wird. priority ist eine Kombination von facility und einem level, die
im nächsten Abschnitt erläutert werden.


sind dann priority beide oder nur einer der Parameter?



EDIT: Also bei z.B. fork, setsid oder chdir braucht man laut den man pages

[code]
#include <unistd.h>


Aber trotzdem bekomm ich die Fehlermeldungen:


[...]
daemon.cpp:10: `fork' undeclared (first use this function)
daemon.cpp:10: (Each undeclared identifier is reported only once for each
function it appears in.)
daemon.cpp:13: `exit' undeclared (first use this function)
daemon.cpp:17: `setsid' undeclared (first use this function)
daemon.cpp:19: `chdir' undeclared (first use this function)
[...]

etc.

Nagilum
2004-01-06, 21:24:14
Original geschrieben von Matrix316
Aber wie ganau würde syslog(... aussehen?

Äh, das printf() nimmste da aber mal ganz schnell wieder raus. :) Könnte dann z.B. so aussehen:


#include <stdlib.h>
#include <syslog.h>


int main(int argc, char** argv)
{
char* appname = "MeinTestchen";

openlog( appname, LOG_PID, LOG_DAEMON );
syslog( LOG_DAEMON | LOG_INFO, "%s wurde gestartet.", appname );
closelog();
return EXIT_SUCCESS;
}


Die Priority ergibt sich durch ein bitweises ODER (|). Je nach Facility und Art der Meldung ergibt sich dann automatisch eine andere Priorität.

Matrix316
2004-01-06, 21:45:31
Also ich hab jetzt drinnen stehen:


syslog(LOG_DAEMON|LOG_INFO,"FEHLER: Daemonisierung nicht moeglich.\n",0);


aber dann kommt der Fehler:


/usr/include/sys/syslog.h:183: too few arguments to function `void syslog(int,
const char*, ...)'


wenn ich aber schreibe:


syslog(LOG_DAEMON|LOG_INFO,"FEHLER: Daemonisierung nicht moeglich.\n");


kommt immer noch der gleiche Fehler...

der Text aus der syslog.h hilft mir aber irgendwie auch net weiter...


void syslog (int __pri, __const char *__fmt, ...) __THROW
__attribute__ ((__format__(__printf__, 2, 3)));

Matrix316
2004-01-06, 21:55:09
Vergiss fast alles des letzten Postings. Das kommt nur davon, wenn man in der Konsole in einem anderen Verzeichnis ist und zu viele kopien von den wichtigen Daten macht...(ich hab die ganze Zeit woanders editiert, als ich kompiliert hab ;D)

Jedenfalls gibts jetzt nur noch einen Fehler:


daemon.cpp: In function `int daemonisieren()':
daemon.cpp:15: `exit' undeclared (first use this function)


Aber bei man exit finde ich auch nix was auch nur annähernd wie eine c funktion (oder include file) aussieht...:|

Matrix316
2004-01-06, 22:11:41
Huiuiui ich habs gefunden. es war die stdlib.h (soviel zum Thema sollte laufen...)

Ok, jetzt zum Webserver, hier mal der Quelltext:


#include "socket.h"

int main()
{
WebServer *ws = new WebServer(80);
ws ->loop();
delete ws;
//return 0;
}


Dahinter stehen jetzt eine socket Klasse und plib-socket mit zig Files.

Wenn ich versuch zu kompilieren kommt jetzt diese Fehlermeldung:


netChannel.h: In function `int main()':
netChannel.h:113: `static void netChannel::loop(unsigned int = 0)' is
inaccessible
webserver.cpp:6: within this context


Die Funktion loop() steht in socket.h/server.cpp und netChannel.cxx/h

server.cpp

[...]
void WebServer::Loop() {
netChannel::loop(1);
}


netChannel.cxx

void
netChannel::loop (u32 timeout)
{
while ( poll (timeout) ) ;
}


was stimmt da net bei mir?

Matrix316
2004-01-07, 11:17:30
Weiß keiner warum das net geht?

Jetzt mal eine blöde Frage: Ich hab hier eine plib-socket Klasse mit jede Menge include Files und *.cxx Files. Muss ich die *.cxx Files noch kompilieren bevor ich die nutzen kann?

Wenn ja wie mach ich das?

mit gcc -o irgendeinname *.cxx gehts schonmal net...

Oder muss ich die nur einbinden bzw. irgendwie dem gcc sagen was für Files noch benötigt werden oder wie?

Das Problem ist, im Programm selbst ist ja nur socket.h, aber die server.cpp (von der socket.h das include ist, braucht noch eine das include File und die Klasse davon braucht wieder andere und die brauchen wieder andere...wie binde ich die ein?

Matrix316
2004-01-07, 20:59:40
HIIIIIIIIIIIIIIIILLLLLLLLLLLLFEEEEEEEEEEEEEEEEE:-(

Hier nochmal der komplette vorläufige Quelltext:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
#include <unistd.h>
#include <stdlib.h>
#include "socket.h"



int daemonisieren()
{
pid_t pid;

if ((pid = fork())<0)
return -1;
else if (pid !=0)
exit(0); //Elternprozess beendet sich

/*Ab hier Kindprozess*/

setsid(); //Kind wird Sessionführer

chdir("/"); //ins Root Directory wechseln

umask (0); //Dateikreierungsmaske loeschen

return 0;
}

int main()
{


if (daemonisieren() !=0)
{
openlog("DAEMON_ws",LOG_PID,0);
//syslog("FEHLER: Daemonisierung nicht moeglich.\n");
syslog(LOG_DAEMON|LOG_INFO," FEHLER: Daemonisierung nicht moeglich.\n");
//printf("Begin...\n");
closelog();
return -1;
}

openlog("daemon_ws",LOG_PID,0);
//syslog("...hallo ich bin jetzt ein Daemon...\n");
syslog(LOG_DAEMON | LOG_INFO,"...hallo ich bin jetzt ein Daemon...\n");
//printf("..weiter...\n");
closelog();

sleep(20);


//webserver(port80)

openlog("daemon_ws",LOG_PID,0);
//syslog("...Deamon has left the building...\n");
//printf("...fertig\n");
syslog(LOG_DAEMON | LOG_INFO,"...Deamon has left the building...\n");
closelog();

WebServer *ws = new WebServer(2048);
ws ->loop();

return -1;
}


es kommt immer noch die Fehlermeldung:


netChannel.h: In function `int main()':
netChannel.h:113: `static void netChannel::loop(unsigned int = 0)' is
inaccessible
daemon.cpp:63: within this context


Was soll die Fehlermeldung überhaupt sagen? Warum kann ich nicht zugreifen???

Xmas
2004-01-07, 21:10:57
Wahrscheinlich weil die Methode nicht public ist.

Matrix316
2004-01-07, 21:20:57
Normal schon:

netChannel.h


#ifndef NET_CHANNEL_H
#define NET_CHANNEL_H

#include "netSocket.h"

class netChannel : public netSocket
{
bool closed, connected, accepting, write_blocked, should_delete ;
netChannel* next_channel ;

friend bool netPoll (u32 timeout);

public:

netChannel () ;
virtual ~netChannel () ;

void setHandle (int s, bool is_connected = true);
bool isConnected () const { return connected; }
bool isClosed () const { return closed; }
void shouldDelete () { should_delete = true ; }

// --------------------------------------------------
// socket methods
// --------------------------------------------------

bool open ( void ) ;
void close ( void ) ;
int listen ( int backlog ) ;
int connect ( cchar* host, int port ) ;
int send ( const void * buf, int size, int flags = 0 ) ;
int recv ( void * buf, int size, int flags = 0 ) ;

// poll() eligibility predicates
virtual bool readable (void) { return (connected || accepting); }
virtual bool writable (void) { return (!connected || write_blocked); }

// --------------------------------------------------
// event handlers
// --------------------------------------------------

void handleReadEvent (void);
void handleWriteEvent (void);

// These are meant to be overridden.
virtual void handleClose (void) {
//ulSetError(UL_WARNING,"Network: %d: unhandled close",getHandle());
}
virtual void handleRead (void) {
ulSetError(UL_WARNING,"Network: %d: unhandled read",getHandle());
}
virtual void handleWrite (void) {
ulSetError(UL_WARNING,"Network: %d: unhandled write",getHandle());
}
virtual void handleAccept (void) {
ulSetError(UL_WARNING,"Network: %d: unhandled accept",getHandle());
}
virtual void handleError (int error) {
ulSetError(UL_WARNING,"Network: %d: errno: %s(%d)",getHandle(),strerror(errno),errno);
}

static bool poll (u32 timeout = 0 ) ;
static void loop (u32 timeout = 0 ) ;
};

#endif // NET_CHANNEL_H


netChannel.cxx


#include "netChannel.h"

static netChannel* channels = 0 ;

netChannel::netChannel ()
{
closed = true ;
connected = false ;
accepting = false ;
write_blocked = false ;
should_delete = false ;

next_channel = channels ;
channels = this ;
}

netChannel::~netChannel ()
{
close();

netChannel* prev = NULL ;
for ( netChannel* ch = channels; ch != NULL;
ch = ch -> next_channel )
{
if (ch == this)
{
ch = ch -> next_channel ;
if ( prev != NULL )
prev -> next_channel = ch ;
else
channels = ch ;
next_channel = 0 ;
break;
}
prev = ch ;
}
}

void
netChannel::setHandle (int handle, bool is_connected)
{
close () ;
netSocket::setHandle ( handle ) ;
connected = is_connected ;
//if ( connected ) this->handleConnect();
closed = false ;
}

bool
netChannel::open (void)
{
close();
if (netSocket::open(true)) {
closed = false ;
setBlocking ( false ) ;
return true ;
}
return false ;
}

int
netChannel::listen ( int backlog )
{
accepting = true ;
return netSocket::listen ( backlog ) ;
}

int
netChannel::connect ( cchar* host, int port )
{
int result = netSocket::connect ( host, port ) ;
if (result == 0) {
connected = true ;
//this->handleConnect();
return 0;
} else if (isNonBlockingError ()) {
return 0;
} else {
// some other error condition
this->handleError (result);
close();
return -1;
}
}

int
netChannel::send (const void * buffer, int size, int flags)
{
int result = netSocket::send (buffer, size, flags);

if (result == (int)size) {
// everything was sent
write_blocked = false ;
return result;
} else if (result >= 0) {
// not all of it was sent, but no error
write_blocked = true ;
return result;
} else if (isNonBlockingError ()) {
write_blocked = true ;
return 0;
} else {
this->handleError (result);
close();
return -1;
}

}

int
netChannel::recv (void * buffer, int size, int flags)
{
int result = netSocket::recv (buffer, size, flags);

if (result > 0) {
return result;
} else if (result == 0) {
close();
return 0;
} else if (isNonBlockingError ()) {
return 0;
} else {
this->handleError (result);
close();
return -1;
}
}

void
netChannel::close (void)
{
if ( !closed )
{
this->handleClose();

closed = true ;
connected = false ;
accepting = false ;
write_blocked = false ;
}

netSocket::close () ;
}

void
netChannel::handleReadEvent (void)
{
if (accepting) {
if (!connected) {
connected = true ;
//this->handleConnect();
}
this->handleAccept();
} else if (!connected) {
connected = true ;
//this->handleConnect();
this->handleRead();
} else {
this->handleRead();
}
}

void
netChannel::handleWriteEvent (void)
{
if (!connected) {
connected = true ;
//this->handleConnect();
}
write_blocked = false ;
this->handleWrite();
}

bool
netChannel::poll (u32 timeout)
{
if (!channels)
return false ;

enum { MAX_SOCKETS = 256 } ;
netSocket* reads [ MAX_SOCKETS+1 ] ;
netSocket* writes [ MAX_SOCKETS+1 ] ;
netSocket* deletes [ MAX_SOCKETS+1 ] ;
int nreads = 0 ;
int nwrites = 0 ;
int ndeletes = 0 ;
int nopen = 0 ;
netChannel* ch;
for ( ch = channels; ch != NULL; ch = ch -> next_channel )
{
if ( ch -> should_delete )
{
assert(ndeletes<MAX_SOCKETS);
deletes[ndeletes++] = ch ;
}
else if ( ! ch -> closed )
{
nopen++ ;
if (ch -> readable()) {
assert(nreads<MAX_SOCKETS);
reads[nreads++] = ch ;
}
if (ch -> writable()) {
assert(nwrites<MAX_SOCKETS);
writes[nwrites++] = ch ;
}
}
}
reads[nreads] = NULL ;
writes[nwrites] = NULL ;
deletes[ndeletes] = NULL ;

int i ;
for ( i=0; deletes[i]; i++ )
{
ch = (netChannel*)deletes[i];
delete ch ;
}

if (!nopen)
return false ;
if (!nreads && !nwrites)
return true ; //hmmm- should we shutdown?

netSocket::select (reads, writes, timeout) ;

for ( i=0; reads[i]; i++ )
{
ch = (netChannel*)reads[i];
if ( ! ch -> closed )
ch -> handleReadEvent();
}

for ( i=0; writes[i]; i++ )
{
ch = (netChannel*)writes[i];
if ( ! ch -> closed )
ch -> handleWriteEvent();
}

return true ;
}

void
netChannel::loop (u32 timeout)
{
while ( poll (timeout) ) ;
}

Matrix316
2004-01-07, 22:01:14
nochwas:

was bedeuten eigentlich unter Linux die Parameter:

int argc, char *argv[]

in der Klammer bei int main (...)

?

Was kann ich damit machen? Bei Kdevelop werden die ja automatisch eingetragen, aber Programme gehen oft auch so...

Matrix316
2004-01-08, 08:56:38
Weiß denn das wirklich wirklich keiner?

Leider habe ich nicht alle Zeit der Welt!!!:-( (Ich muss den scheiß bis Sonntag fertig haben und dann noch für 2 Klausuren lernen die wir gleich am Montag schreiben)

Es eilt WIRKLICH! =):bawling:

Weiß dann wenigstens jemand wo ein gutes Linux-Programmierungs-C(++)-Tutorial zu finden wäre?

HellHorse
2004-01-08, 11:12:17
Aufgrund der Namen hätte ich gesagt die Argument und die Anzahl Argumente, und was man damit machen kann, ist dem Programm Argumente übergeben ;)

Matrix316
2004-01-08, 12:05:19
Original geschrieben von HellHorse
Aufgrund der Namen hätte ich gesagt die Argument und die Anzahl Argumente, und was man damit machen kann, ist dem Programm Argumente übergeben ;)

Das ist ein Argument. :arsch: ;) (nur spaß)

Jedenfalls ist erstmal wichtiger warum geht die scheiß loop Funktion nicht?

Muss ich aus den cxx Dateien Objektdateien machen?

Das hab ich mal probiert und wollte die dann kompillieren, aber der meckert immer mit dem scheiß loop da rum.

Warum kann ich die Funktion nicht nutzen???

Oder hängt das an den Benutzerrechten der Files???

Ich hab keine Ahnung...das gibts doch garnet...:banghead: :motz:

PS.: Ich hab hier sogar eine Lösung aber selbst das kann ich irgendwie nicht kompilieren, weil es da wieder andere Fehlermeldungen gibt.

PPS.: Reicht es nicht um Klassen einzubinden das Include-File einzubinden? Visual Studio macht ja praktisch alles alleine, aber wie zum Geier geht das mit gcc oder g++, jedenfalls von der Konsole aus?

Xmas
2004-01-08, 14:17:20
Original geschrieben von Matrix316
nochwas:

was bedeuten eigentlich unter Linux die Parameter:

int argc, char *argv[]

in der Klammer bei int main (...)

?

Was kann ich damit machen? Bei Kdevelop werden die ja automatisch eingetragen, aber Programme gehen oft auch so...
Hat nichts mit Linux zu tun, das ist C-Standard.
argc ist die Anzahl der Kommandozeilenparameter. Immer >= 1.

argv ist ein Pointer auf eine Null-terminierte Liste von Null-terminierten Strings. Eigentlich müsste die Liste nicht Null-terminiert sein, weil man ja schon mit argc die Länge kennt, aber irgendjemand hat sich wohl was dabei gedacht.
So kann man mit
while(*(argv++)) {
/* tu was mit *argv ... */
}
die Liste durchlaufen.

Wichtig ist, dass die Liste immer mit dem Namen der ausgeführten Datei anfängt. Also wenn die Kommandozeile "hallo.exe -a" heißt, bekommst du zwei Listenelemente, "hallo.exe" und "-a" (sowie die abschließende Null).

Xmas
2004-01-08, 14:24:10
Matrix316,
ersetze mal das l von loop durch L ... ;)


netChannel::loop() ist static, WebServer::Loop() wohl nicht (hoffe ich doch?). Du kannst somit kein ws->loop() aufrufen, weil du static-Methoden nicht mit Instanz aufrufen kannst. ws->Loop() dagegen sollte gehen (sofern WebServer::Loop() nicht static ist).
Oder du schreibst statt ws->Loop() eben netChannel::loop() ...

Matrix316
2004-01-08, 14:24:51
Heißt das, wenn ich z.B. ein Programm webserver und dann als Parameter ein Verzeichnis oder so angebe:

webserver ~/Hallo/html

wäre dann ~/Hallo/html praktisch das Argument was bei main(...) als Argument reinkommt?


Nochwas zu dem Loop: Also ich glaube mit dem Einbinden der Klassen hat das nichts zu tun. Ich hab mal was ganz verrücktes gemacht ;), nämlich ein leeres Projekt in Kdevelop. Dann hab ich die ganzen Dateien eingebunden und das Hauptfile. Da wurden die ganzen plib-socket/socket Klassen schön aufgezeigt. Dann als ich das Hauptprogramm kompilieren wollte kam wieder die schöne Fehlermeldung:


g++ -c -o daemon.o daemon.cpp
netChannel.h: In function `int main()':
netChannel.h:113: `static void netChannel::loop(unsigned int = 0)' is
inaccessible
daemon.cpp:63: within this context
gmake: *** [daemon.o] Fehler 1
*** fehlgeschlagen ***


Ich hab mir auch extra nochmal die plib-socket und socket Files neu downgeloaded (die sind ja net von mir).

Warum geht das net???

Xmas
2004-01-08, 14:30:02
Original geschrieben von Matrix316
Heißt das, wenn ich z.B. ein Programm webserver und dann als Parameter ein Verzeichnis oder so angebe:

webserver ~/Hallo/html

wäre dann ~/Hallo/html praktisch das Argument was bei main(...) als Argument reinkommt?
Du bekommst eine Liste mit sowohl "webserver" als auch "~Hallo/html". (Unter UNIX und Derivaten wird die Shell wahrscheinlich ~ mit dem entsprechenden Home-Verzeichnis ersetzen)

Matrix316
2004-01-08, 14:31:50
Original geschrieben von Xmas
Matrix316,
ersetze mal das l von loop durch L ... ;)

NEEEEEEEEEEEEIIIIIIIIIINNNNNNN

Jo, jetzt gehts...:chainsaw: :lol: :bonk: :spritz:

Matrix316
2004-01-08, 14:35:25
...immer noch nicht.

Ok, die Fehlermeldung ist weg, aber jetzt kommen wieder neue (die hab ich auch, wenn ich die Lösung die ich hab kompilieren will):


gcc -o webserver daemon.cpp
/tmp/cc6jnCWr.o(.text+0x10e): In function `main':
: undefined reference to `operator new(unsigned)'
/tmp/cc6jnCWr.o(.text+0x128): In function `main':
: undefined reference to `WebServer::WebServer[in-charge](int)'
/tmp/cc6jnCWr.o(.text+0x151): In function `main':
: undefined reference to `operator delete(void*)'
/tmp/cc6jnCWr.o(.text+0x176): In function `main':
: undefined reference to `operator delete(void*)'
/tmp/cc6jnCWr.o(.text+0x184): In function `main':
: undefined reference to `WebServer::Loop()'
/tmp/cc6jnCWr.o(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status

Matrix316
2004-01-08, 21:02:30
Weiß dann wenigstens jemand was die Fehlermeldung:

[...] In function `main':
: undefined reference to `operator [...]

bedeutet?

Matrix316
2004-01-08, 21:04:33
WICHTIGE Entdeckung!!!

Ich hab gerade was gefunden und zwar in einem Forum hatte jemand ähnliche Fehlermeldungen und da kam als Antwort:


The current SDK arm libraries are built with gcc 2.95, so you need to
use this when building the final application (ABI differences between
gcc 2.95 and 3.2). --Kent


Kann das auch hier der Fall sein?

Gast
2004-01-08, 21:47:41
Probier mal g++ statt gcc oder füg als Parameter -lstdc++ hinzu.
Kann aber auch sein, dass ich mich grad irre.

Matrix316
2004-01-08, 21:59:06
JUHU es geht!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;D

Aber manchmal denkt man, man wäre blöd...;)

Also wer wissen will wie mans macht, hier die Anleitung:

Wichtig war, dass Loop überall gleich geschrieben wird, das war nämlich nicht der Fall...(WARUM auch immer...:|)

Dann kompilieren:

gcc -c *.cxx
gcc -c *.cpp

und jetzt der Kasus Knaxus das erstellen:

g++ -o NamedesFiles *.o //Objektdateien die vorher erstellt wurden

Aber eine Frage hab ich noch:

Woher weiß ein Webserver, DASS er was "servieren" soll?

Matrix316
2004-01-08, 21:59:51
Original geschrieben von Gast
Probier mal g++ statt gcc oder füg als Parameter -lstdc++ hinzu.
Kann aber auch sein, dass ich mich grad irre.

g++ hat schon gereicht.

Aber wie man als normalsterblicher darauf kommen soll...=)

grakaman
2004-01-08, 22:49:51
Original geschrieben von Matrix316
Aber eine Frage hab ich noch:

Woher weiß ein Webserver, DASS er was "servieren" soll?

Indem er an einem bestimmten Port lauscht, für gewöhnlich 8080. Den Rest bekommst du ja über das TCP/IP und HTTP Protokoll heraus.

Matrix316
2004-01-09, 19:17:38
Und was macht der Webserver bzw. durch welche Aktion sendet er etwas (was?) an einen Browser?

Wenn ich z.B. eine Webseite mit einem Bild habe, und ich öffne diese Seite und sie erscheint im Browser. Wo bzw. wie funktioniert dann der Webserver wenn ich diesen Starte und diesem z.B. ein Verzeichnis mit den Daten der Webseite gebe?

Bei uns im Skript steht z.B. das:

-Auf Anfrage vom Webserver vom Webbrowser sendet der Webserver die entsprechend angeforderten Dateien.

Wer fordert wie was an?

-Der Browser nimmt eine Verbindung an den Server zu Port 80 auf.

Muss der Browser schon gestartet sein wenn der Webserver aktiviert wird?

-Es können Daten vom Client zum Server und umgekehrt gesendet werden, bis einer von beiden die Verbindung abbricht.

Was ist der Client? Der Browser? Woher hat der Server die Daten die er schicken soll? Ist das die Webseite die ich erstellt habe (Wahrscheinlich ;))? Wie kann ein Browser Daten an den Server schicken?

Ich meine, was ein Webserver (ein PC der am Internet angeschlossen ist und eine Seite "serviert") ist, ist mir bekannt :D, aber was ist der Unterschied zu einem Webserver (der Software)???

Oder gibts keinen?

Matrix316
2004-01-10, 00:30:07
Jetzt noch eine kleine Frage zum Aufwärmen. ;)

Ich hab eine Klasse mit zwei Methoden:


void myPfad::savePfad(char *VerzeichnisPfad)
{
myPfad_1=VerzeichnisPfad; //myPfad_1 ist private deklariert
}

char* myPfad::returnPfad()
{
return myPfad_1;
}

Die Rufe ich auf mit:


myPfad::savePfad(argv[1]);

und

myPfad::returnPfad() //in Verbindung mit sprintf z.B.


Da bekomm ich beim kompilieren die Fehlermeldungen:


channel.cpp: In member function `virtual void
Channel::handleBufferRead(netBuffer&)':
channel.cpp:26: cannot call member function `char* myPfad::returnPfad()'
without object
daemon.cpp: In function `int main(int, char**)':
daemon.cpp:55: cannot call member function `void myPfad::savePfad(char*)'
without object


Aber eigentlich sollte die Funktion äh Methode ;) auch ohne Objekt funktionieren, oder?

Nagilum
2004-01-10, 13:09:01
Original geschrieben von Matrix316
Aber eigentlich sollte die Funktion äh Methode ;) auch ohne Objekt funktionieren, oder?

Ist sie denn als "static" deklariert?

Matrix316
2004-01-10, 13:12:35
Original geschrieben von Nagilum
Ist sie denn als "static" deklariert?

Nö...wäre das wichtig?

Es geht z.B. wenn ichs so mach:

myPfad test;

test.myPfad::returnPfad();

Aber das will ich ja garnet...

Nagilum
2004-01-10, 13:18:58
Ja. Du willst ja nicht auf die Instanz einer Klasse zugreifen, sondern auf eine Klassemethode. Kennst du doch schon von der, äh, *such*, Loop() Methode.

Matrix316
2004-01-10, 13:32:02
Ich hab hier aber eine Klasse mit Methoden die ähnlich aufgebaut sind und die auch nicht static sind...

Nagilum
2004-01-10, 13:43:39
Du rufst Klassenmethoden auf, die nicht als "static" deklariert sind?

Ich lern bei C++ wirklich nie aus...

Matrix316
2004-01-10, 13:49:01
Also static geht nicht. Es kommen Fehlermeldungen:


cannot declare member function `static void
myPfad::savePfad(char*)' to have static linkage
myPfad.cpp: In static member function `static void myPfad::savePfad(char*)':
myPfad.cpp:15: invalid use of member `myPfad::myPfad_1' in static member
function
myPfad.cpp: At global scope:
myPfad.cpp:19: cannot declare member function `static char*
myPfad::returnPfad()' to have static linkage
myPfad.cpp: In static member function `static char* myPfad::returnPfad()':
myPfad.cpp:20: invalid use of member `myPfad::myPfad_1' in static member
function


Ich hab hier z.B. eine Klasse mit:


void pathfinder::logAusgabe(char* fehler)
{
openlog("DAEMON", LOG_PID, LOG_LOCAL1);
syslog (LOG_MAIL,"%s",fehler);
closelog();

}

die wird mit

pathfinder::logAusgabe(irgendwas);

aufgerufen und das funktioniert und ist ja auch nicht static...

Nebenbei: Gibts eigentlich unter Linux irgendwo die Funktion str2num ?

Nagilum
2004-01-10, 13:54:11
Hast du das "static" etwa in das *.cpp File gepackt?
Und die Membervariable muss natürlich auch statisch sein.

Matrix316
2004-01-10, 13:56:36
Original geschrieben von Nagilum
Hast du das "static" etwa in das *.cpp File gepackt?
Und die Membervariable muss natürlich auch statisch sein.

1. Jo, und das war falsch hab ich gerade gemerkt...;D

2. Ja, das hab ich auch gesehen...;)

Naja, jetzt gehts.

Jetzt fehlt mir nur noch die Funktion str2num, welche angeblich in string.h drin sein soll, aber bei mir net...:|

Oder wo könnte die noch drinnen sein?

man str2num geht nicht, bzw. er findet nix.

Nagilum
2004-01-10, 14:03:50
Was macht das? String in eine Zahl umwandeln?

Probier mal "man atoi".

Matrix316
2004-01-10, 14:06:47
Original geschrieben von Nagilum
Was macht das? String in eine Zahl umwandeln?

Probier mal "man atoi".

Ja, string to number.

(Jetzt hab ich das auch mit den Argumenten verstanden)

Jedenfalls starte ich das Programm mit zwei Argumenten. Die zweite ist eine Zahl, aber die kommt ja als char * ins Programm rein.Ich brauch aber eine int Zahl und Typecast geht irgendwie auch net.

Aber anscheinend macht atoi genau das was ich will. :)