Compilieren?
-
Ich habe mir folgendes Programm im Web angeschat und moechte es gerne Compilieren (Sun) jedoch wenn ich den Befehl dazu eingebe (gcc -o simple_www_server simple_www_server.c) kommte nur die Fehlermeldung:
Undefined first referenced
symbol in file
listen /var/tmp//ccWNcNMa.o
accept /var/tmp//ccWNcNMa.o
socket /var/tmp//ccWNcNMa.o
bind /var/tmp//ccWNcNMa.o
ld: fatal: Symbol referencing errors. No output written to simple_www_server
collect2: ld returned 1 exit statusObwohl dies so angeben ist das man das auf diese Weise erledigen koenne
Einfacher Web-Server in C
Übersetzen: gcc -o simple_www_server simple_www_server.c
Starten: ./simple_www_server
simple_www_server.c/*
* simple_www_server.c
* Einfacher WWW-Server
* Rudolf Kugel, Fre Jan 19 14:31:59 CET 2001
*/#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>#define SERVER_PORT 8082
#define XMIT_BUFSIZE 1024
#define MAX_FILEPATHNAMELEN 1024#define HTTP_MABBR_GET "GET"
typedef enum
{
HTTP_ERROR_CODE_BAD_REQUEST = 400,
HTTP_ERROR_CODE_FILE_NOT_FOUND = 404
} HTTP_ERROR_CODE;int current_request_socket; /* Verbindung die zur Abwicklung der in Bearbeitung befindlichen Anfrage benutzt wird */
char receive_buffer[XMIT_BUFSIZE]; /* Puffer für blockweisen Emfang von HTTP-Anfragen /
int receive_buffer_nbytes; / Zahl der aktuell im Empfangspuffer befindlichen Zeichen */char send_buffer[XMIT_BUFSIZE]; /* Puffer für blockweisen Versand von Anfrageergebnissen (HTML-Seiten) /
int send_buffer_nbytes; / Zahl der aktuell im Sendepuffer befindlichen Zeichen *//* Diese Prozedur bricht das Programm mit einer Fehlermeldung ab. */
void error_exit(char *text)
{
char buf[256];sprintf(buf, "\7\7\nEs ist ein Fehler aufgetreten: %s \n.", text);
perror(buf);
exit(1);} /* error_exit() */
/* Diese Prozedur empfängt einen Block der vom Client (WWW-Browser) kommenden
* Anfrage entgegen und legt ihn im Empfangspuffer Receive_buffer ab.
* (receive_buffer_nbytes enthält die Anzahl der im Puffer abgelegten Bytes.)
*/
void receive_chunk()
{
fprintf(stderr, "Server receiving chunk ... ");
receive_buffer_nbytes = read(current_request_socket, receive_buffer, sizeof(receive_buffer));
fprintf(stderr, "of %d bytes size \n", receive_buffer_nbytes);if (receive_buffer_nbytes < 0)
error_exit("receive_chunk()");} /* receive_chunk() */
/* Diese Prozedur sendet den Inhalt des Sendepuffers an den Client (WWW-Browser).
* (Der Inhalt des Sendpuffers sind die "send_buffer_nbytes" ersten bytes in send_buffer. )
*/
void send_chunk()
{
int nbytes;fprintf(stderr, "Server sending chunk ... ");
nbytes = write(current_request_socket, send_buffer, send_buffer_nbytes);
fprintf(stderr, "of %d bytes size \n", nbytes);if (send_buffer_nbytes != nbytes )
error_exit("send_chunk()");} /* send_chunk() */
/* Diese Prozedur dient dazu, die bekannten Standardantworten wie
* "404 File not found" an den Client (WWW Browser) zurückzusenden.
*/
void handle_HTTP_ERROR(HTTP_ERROR_CODE http_error_num)
{
switch ( http_error_num)
{
case HTTP_ERROR_CODE_BAD_REQUEST:
strcpy( send_buffer, "HTTP/1.0 400 Bad Request\nServer: HPIlabor/1.0\nConnection: close\nContent-Type: text/html; charset=iso-8859-1\n\n<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n");
send_buffer_nbytes = strlen(send_buffer) + 1;
send_chunk();
break;
case HTTP_ERROR_CODE_FILE_NOT_FOUND:
strcpy( send_buffer, "HTTP/1.0 404 Not Found\nServer: HPIlabor/1.0\nConnection: close\nContent-Type: text/html; charset=iso-8859-1\n\n<html><head><title>404 File not found</title></head>\n");
send_buffer_nbytes = strlen(send_buffer) + 1;
send_chunk();
break;
}
}/* Diese Prozedur kümmert sich um die Beantwortung von HHTP_GET anfragen.
*/
void handle_HTTP_GET()
{
char *filepathname_bufferstartpos;
char *filepathname_destpos;char filepathname[MAX_FILEPATHNAMELEN];
FILE *file;
struct stat file_stat;long filesize;
char* contenttype;/* Zunächst die Anfrage analysieren / vollständig entgegennehmen */
/* Dateinamen der angefordeten Datei aus REQUEST extrahieren und in filepathname speichern. */
filepathname_bufferstartpos = strstr( receive_buffer, "/" );
filepathname_destpos = filepathname;
while ( (*filepathname_bufferstartpos) != ' ')
{
(*filepathname_destpos) = (*filepathname_bufferstartpos);
*filepathname_destpos++;
*filepathname_bufferstartpos++;
}
*filepathname_destpos = '\0';
perror( filepathname );
/* Rest des Anfragetextes einlesen *//* Informationen zur Beantwortung des Request zusammentragen */
/* Existiert die angeforderte Datei überhaupt, handelt es sich wirlich um
* eine Datei (und nicht um ein Verzeichnis, Gerät, Pipe o.ä.) und welche
* größe hat sie ?
*/
if( stat( filepathname, &file_stat) != 0 )
{ /* Es konnten keine Informationen über die Datei des angegebenen
* Namens ermittelt werden: vermutlich existiert die Datei nicht
*/
handle_HTTP_ERROR( HTTP_ERROR_CODE_FILE_NOT_FOUND );
return;
} else if ( !(S_ISREG(file_stat.st_mode)) )
{ /* Der angegebene Name war kein Dateiname, sondern ein Verzeichnisname oder ... */
handle_HTTP_ERROR( HTTP_ERROR_CODE_BAD_REQUEST );
return;
} else
{ /* Der angegebene Name identifizierte wirklich eine reguläre Datei. */
filesize = file_stat.st_size;
}/* MIME Type über Dateiendung ermitteln */
if ( strcmp( ".html", &(filepathname[strlen(filepathname) - 5]) ) == 0 ) {
contenttype = "text/html";
} else if ( strcmp( ".gif", &(filepathname[strlen(filepathname) - 4]) ) == 0 ) {
contenttype = "image/gif";
} else if ( strcmp( ".jpg", &(filepathname[strlen(filepathname) - 4]) ) == 0 ) {
contenttype = "image/jpg";
} else if ( strcmp( ".mid", &(filepathname[strlen(filepathname) - 4]) ) == 0 ) {
contenttype = "audio/midi";
} else if ( strcmp( ".class", &(filepathname[strlen(filepathname) - 5]) ) == 0 ) {
contenttype = "application/java";
} else {
contenttype = "unknown";
}/* Anfrageergebnis zurückschicken */
/* Zunächst HEADER zusammensetzen und verschicken. */
sprintf( send_buffer, "%s%s%s%s%s%s%s%s%d%s%s%s%s%s%s",
"HTTP/1.0 200 OK\n",
"Server: HPIlabor/1.0\n",
"Last-Modified: ", __DATE__, ", ",__TIME__, "\n",
"Content-Length: ", filesize , "\n",
"Connection: close\n",
"Content-Type: ", contenttype, "\n",
"\n"
);
send_buffer_nbytes = strlen(send_buffer);
send_chunk();/* INHALT der angefragten Datei hinterherschicken */
file = fopen( filepathname, "r");
while ( !feof( file ) )
{
/* Nächsten Block aus der Quelldatei in Sendepuffer kopieren */
send_buffer_nbytes = fread( send_buffer, sizeof(char), XMIT_BUFSIZE, file );
/* Pufferinhalt versenden */
send_chunk();
}
fclose( file );} /* handle_HTTP_GET() */
/* Die Prozedur analysiert die eingehenden Anfragen und verzweigt je nach
* HTTP Methode in die entsprechende Prozedur zur Beantwortung von Anfragen
* dieses Typs. (bisher wird nur GET wirklich beantwortet)
*/
void dispatch_request( )
{
char *method;/* HTTP Request soweit einlesen, wie zum Dispatch erforderlich */
receive_chunk();/* REQUESTTYP feststellen und Bearbeitung einleiten */
method = receive_buffer;
if ( strncmp(method, HTTP_MABBR_GET, strlen( HTTP_MABBR_GET ) ) == 0 )
{
handle_HTTP_GET();
}
else
{
handle_HTTP_ERROR( HTTP_ERROR_CODE_BAD_REQUEST );
}} /* dispatch_request() */
/* Hauptprogramm:
* Hier wird zunächst der Serverdienst eingerichtet, sodaß die eingehenden
* Anfragen auch tatsächlich zu diesem Server weitergeleitet werden.
* Danach werden die eigehenden Anfragen nscheineinder bearbeitet (Endlosschleife).
*/
int main(int argc, char **argv)
{
int server_socket;
int client_len, rval;
struct sockaddr_in client_addr, server_addr;/* Socket erzeugen */
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
error_exit("Server Socket konnte nicht erzeugt werden.");/* Socket an Adresse binden.
(Dadurch wird festgelegt welche am Rechner ankommenden Anfragen an den
neu erzeugten Socket weiterzuleiten sind. Hier sind es alle Anfragen
die von irgendwelchen Ports anderer Rechner ausgehen und an den Port
mit der Nummer "SERVER_PORT" gerichtet sind.)
*/
bzero((char &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
rval = bind(server_socket, (struct sockaddr &server_addr, sizeof(server_addr));
fprintf(stderr, "Server: bind %d\n", SERVER_PORT);
if (rval < 0)
error_exit("main():bind");/* Socket aktivieren (Empfangsbereitschaft herstellen). Für den Fall daß mehr
* Anfragen eintreffen als gleichzeitig bearbeitet werden können (Es kann zu
* jedem Zeitpunkt immer nur eine Anfrage bearbeitet werden), soll eine
* Warteschlange für maximal 5 anstehende Verbindungswünsche eingerichtet werden.
*/
rval = listen(server_socket, 5);
fprintf(stderr, "Server: listen %d\n",SERVER_PORT);
if (rval < 0)
error_exit("main():listen");/* Hauptschleife (endlos): Auf eingehende Anfragen warten und diese beantworten. */
for (;;) {
/* Auf Nächste Anfrage eines HTTP clients (Browsers) warten.
* Sobald eine Anfrage für den Port SERVER_PORT eintrifft, landet diese
* am server_socket. Daraufhin wird eine neuer socket (eigens für diese
* Anfrage) angelegt und der Anfragende wird samt Anfrage dorthin
* weitervermittelt. Der Identifikator dieses zweiten sockets wird
* in current_request_socket gespeichert.
*/
fprintf(stderr, "\n\nServer accepting connection ... ");
client_len = sizeof(client_addr);
current_request_socket = accept(
server_socket,
(struct sockaddr &client_addr,
&client_len
);
fprintf(stderr, "%d\n", current_request_socket);
if (current_request_socket < 0)
error_exit("main():accept");/* Bearbeitung des REQUESTS anstossen */
dispatch_request();/* Verbindung zum letzten Client wieder schliessen */
close(current_request_socket);
}return 0;
} /* main() */
.
[cpp]
vielen DAnk fuer den Hinweis
-
Ich glaube (hab selber keine Sun) dass du die Socket Library einlinken musst ... -lsocket