Servidor web escrito en C

Iniciado por Psicotron, 13 Noviembre 2009, 18:47 PM

0 Miembros y 1 Visitante están viendo este tema.

Psicotron

Hola gente! Investigando en la web como funciona un servidor web. El tema de las peticiones y los header de las mismas me desidi a escribir un servidor web minimo como para probar las funciones http.
No soy muy bueno con el C ya que vengo del Basic  pero ya habia probado uno en VB pero se me hacia muy lento y se colgaba entonces buscando ejemplos en la web de como hacer conexiones TCP , como interpretar el comando GET que envia el navegador web con los datos de la pagina que le esta pidiendo al servidor.
El codigo esta escrito y probado bajo un sistema OS X en n a ibook ya que no tenia instalado linux en otra pc y queria que funcionara bajo una plataforma similar a UNIX.
E programa funciona bien en unix pero el problema ovio es cuando lo quise portar a Windws y no se como y cuales librerias debo incluirle y si tengo que cambiarle algo mas al codigo asi que lo publico y quien tenga ideas para el codigo bienvenido sea de corregirlo.
Ya que el mas famoso se llama Apache al mio como vendria a ser un primo lejano del subdesarrollo le puse Warani Server :laugh:

Citar//***********************************************************************************************************
//*********************************************** WARANI SERVER ver 0.01 ************************************
//*Este es el codigo de un servidor de paginas HTML basado en codigos de ejercicios de tranferencia de datos*
//*por TCP y otros que dan vueltad por la red. Como se daran cuenta es un servidor minimo pero efectivo el  *
//*cual responde bien a las peticiones de los navegadores mas usados lease : Zorro de fuego , Explorador y  *
//*el de la manzanita tambien.                                                                              *
//*De mas esta decir que el codigo esta liverado bajo la norma GPL V2 asi que pueden descargarlo, mejorarlo *
//*(eso es lo primero que deben hacer) y usarlo a gusto.                                                    *
//*Acepto sugerencias a este mail: warani_project@hotmail.com                                               *
//***********************************************************************************************************

#ifndef WIN32
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#else //---------------------- Aqui se incluyen los Headers para que funcione en Windwz------//
   #include <windows.h>
   #include <winsock.h>
#endif


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
 char* ver = "0.01";//------------Esta es la version//
 int mi_socket, nuevo, tam;
 FILE *archivo;//----------------Puntero de la funcion que abre el archivo//
 int  caracter;
 char* paginaerror = "<html><head><title>Error 404</title></head><body><p>No exixte esa pagina</p></body></html>";//-----Puntero del string error de pagina//
 int suma, len;
 int auxiliar;
 char bufrecv[1024];//----------Buffer para recepcion de datos del cliente//
 char bufenv[1024];//-----------Buffer para los datos que se enviaran//
 struct sockaddr_in mi_estructura;
 struct sockaddr_in dir_remota;
 char nombrepag[50];//----------Variable para el nombre de la pagina pedida//
 int cont = 0;
 
 printf("\n******************** WARANI SERVER Ver:%s ********************\n", ver);
//------------------------------Inicializa la estructura de conexión-------------------------------------//
 mi_estructura.sin_family = AF_INET;
 mi_estructura.sin_port =9999;//---------Aqui establecemos el puerto que va a escuchar(para html es el puerto 80//
 mi_estructura.sin_addr.s_addr = INADDR_ANY;//---La direccion ip del servidor en este caso localhost//
 memset( &(mi_estructura.sin_zero), '\0', 8 );

 mi_socket = socket( AF_INET, SOCK_STREAM, 0 );
 tam = sizeof( struct sockaddr );

 bind( mi_socket, (struct sockaddr *)&mi_estructura, tam );
 listen( mi_socket, 5 );//-Comienza la escucha del servidor, se establecen hasta 5 conexiones entrantes//
 printf("Escuchando...\n");
 
 while( 1 ) //-------------Bucle infinito para tratar conexiones//
 {
   nuevo = accept( mi_socket, (struct sockaddr *)&mi_estructura, &tam);//---Acepta conexión entrante//
                   
   printf("%s Conectado\n", inet_ntoa(dir_remota.sin_addr)); //-------------Imprime la direccion IP del cliente//
   
   len = recv(nuevo, bufrecv, 1024, 0); //----------------------------------Recibe la peticion del cliente//
   bufrecv[len] = '\0';
   printf("%s\n", bufrecv);//---------Imprime la peticion del cliente//
   auxiliar=0;
   while (bufrecv[5+auxiliar] != ' ') //--Aqui se busca despues del GET la pagina pedida//
     {
       nombrepag[auxiliar] = bufrecv[5 + auxiliar];
       auxiliar++;
     }
   
    if(auxiliar < 1 ) //--Si la peticion es la pagina prinsipal osea '/' se enviara "index.html"//
     strcpy(nombrepag, "index.html");
    else
     nombrepag[auxiliar] = '\0';
     printf("%s\n", nombrepag);


//----------------------Aqui comiensa la sección de envio de datos------------------------//
   if( fork() == 0 )
   { // hijo
     close( mi_socket ); // El proceso hijo no lo necesita
   
  //-----------Abre el archivo de texto-----------//      
   if ((archivo = fopen ( nombrepag, "r")) != (FILE *)0)
   {   
 cont = 0;
   while ((caracter = getc(archivo)) != EOF)//--Mientras no sea el final del archivo leera un caracter tras otro//
    {
      bufenv[cont++] = caracter ;
      if (cont >= 1024)
    {
      send (nuevo, bufenv, cont, 0);//---Envia datos al cliente si el Buffer de envio se ha llenado//
      cont = 0;
    }
    }
      send (nuevo, bufenv, cont, 0);//---Envia datos al cliente si se llego al final del archivo//
    }
     else
   {
     send (nuevo, paginaerror,strlen(paginaerror),0);//---Envia pagina de error 404//
     }

     fclose(archivo);
     close( nuevo );
     printf("%d Bytes enviados\n", suma);//----Imprime la cantidad de Bytes enviados//
   
     exit( 0 );
   } else { // padre
     close( nuevo );  // El proceso padre no lo necesita
 
 }
 }

 return 0;
}


En rojo esta marcado el codigo que saque de un foro para que funcione en Wndws pero a mi no me compilo y me tiro error asi que los que lo quieran probar en linux borren esa parte del code que funciona bien.
El puerto de escucha esta en 9999 pero si quieren pero para no tener problemas cambienlo a 80.
Para los que lo dejan en 9999 y quieren probar en un navegador deben poner en la ventana de direcciones " http://localhost/index.html:9999"
Tambien deben crear una pagina la cual van a pedir (mejor que sea index.html que la busca  por defecto).

Bueno espero que les sea util el codigo y si encuentran la forma de portrlo a windows publiquenlo que es una buena ayuda.

VI ROOT Y ENTRE!!!

☺BADMAN

 :D

  Estos son los soucrce que me gustan ver  :rolleyes: como que me voy a quedar mas tiempito por aqui Gracias ....  ;D
Experto en Biefrost.
Subseven User.
Especialista en crypters.
Tifa FAN
Batch Programer XD ;D

Zzombi

hola

está bueno el code gracias

pero en windows no funcionará porque ocupas fork() para crear procesos... y eso es de linux.. bueno entre otras cosas que estás ocupando propias de linux.


saludos.

Psicotron

No tenia idea que FORK no funcionaba en Windz ya que siempre programe c para Unix. Entonces no se puede cambiar esa parte del codigo por una que funcione en Windwz? Mi idea es que si alguien sabe como que aporte su conocimiento.
VI ROOT Y ENTRE!!!

Jaixon Jax

  Bueno puedes detectar el so si es windows ejecutas una api de windows y si no utilizas el fork() .....

Zzombi

tendrias que crear un hilo... que se dedique a enviar los datos...

con la api CreateThread.. y que reciba como parametro el nombre del archivo... eje: index.html

Psicotron

Me pasa algo gracioso.  Lo quiero volver a compilar y compila pero no funciona.  Pasaron varios años y antes funcionaba pero ahora no.  Alguno lo puede revisar?
VI ROOT Y ENTRE!!!

AlbertoBSD

Es el mismo sistema y compilador?

Que cambio.

Estoy trabajando en algo similar, pero lo quiero haces mas generico usando una tabla de estados (AUTOMATA) para determinar en que punto de la peticion estoy, ya sea el GET el host, las cookies la conexion entre otros.

Pero mejor no desvio este tema.

Es exactamente el mismo codigo?

Que error te da?

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW