domingo, 23 de septiembre de 2012

Curso de sockets. Capitulo 2. Como programar un webserver

Capítulo perteneciente al curso de programación C/C++  LordPakus

Hola a todos,

El capítulo de hoy se centrará en programar un servidor de web html.

Un servidor web no es más un programa que usa los sockets para dar información que pueden representar los navegadores ( html )

Si nosotros montamos un servidor como el del capitulo anterior pero que está vez envie html al cliente ya tendremos un servidor web bien sencillo.

El código es el siguiente:


#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <string.h>

#pragma comment(lib, "Ws2_32.lib")
#define PUERTO 8080

WSADATA wsa;

int error()
{
    std::cout << "Error #" << GetLastError() << std::endl;
    WSACleanup();

    getchar();

    return 0;
}

int InitServer(sockaddr_in *local, SOCKET * servidor, int puerto)
{
local->sin_port = htons(puerto); // Puerto a la escucha.
local->sin_family = AF_INET; // Debe ser AF_INET.
local->sin_addr.S_un.S_addr = INADDR_ANY; // Usar cualquier dirección.

*servidor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   // Protocolo TCP
   
if(*servidor == INVALID_SOCKET)
return error();

if(bind(*servidor, (sockaddr*)local, sizeof(sockaddr)) == SOCKET_ERROR)
return error();

if(listen(*servidor, 1) == SOCKET_ERROR)     // Colocamos el servidor a la escucha.
return error();

std::cout << "Servidor a la escucha por el puerto " << puerto << ", esperando conexión." << std::endl;

return 0;
}

void WaitConnection(SOCKET *servidor, SOCKET * nueva_conexion )
{
do
{
*nueva_conexion = accept(*servidor, NULL, NULL); // Esperamos una conexión entrante y la aceptamos.
} while(*nueva_conexion == SOCKET_ERROR);
}

void SendMessage(SOCKET conexion,char *str)
{
send(conexion,str,strlen(str),0);
}

int WaitMessage(SOCKET conexion, char *bufout)
{
int bytes_recv;
char buffer[512];

memset(buffer, 0, sizeof(buffer)); // Limpiamos el buffer temporal
memset(bufout, 0, sizeof(buffer)); // Limpiamos el buffer de salida.

do
{
bytes_recv = recv(conexion, buffer, sizeof(buffer), 0);   // Esperamos para recibir datos...
} while(bytes_recv == 0 && bytes_recv != SOCKET_ERROR);

//Copiamos el buffer temporal en el de salida
memcpy(bufout,buffer,bytes_recv);

return bytes_recv;

}

int Server(void)
{
int res;
SOCKET servidor, nueva_conexion;
sockaddr_in local;
char buffer[512];
int bytes;

//Iniciamos el servidor
res = InitServer(&local,&servidor, PUERTO);

if ( res )
return res;

while(1)
{
//Esperamos que se nos conecte un cliente
WaitConnection(&servidor,&nueva_conexion);

std::cout << "Conecction received" << std::endl;

bytes = WaitMessage(nueva_conexion,buffer);

if(bytes > 0)
std::cout << "Buffer: " << buffer << " - Bytes recibidos: " << bytes << std::endl;

SendMessage(nueva_conexion,"<HTML><HEAD><TITLE>Un Titulo para el Browser de turno </TITLE></HEAD><BODY><H3>Pongamos un subtítulo<H3></BODY></HTML>");

closesocket(nueva_conexion);                                    // Lo desconectamos!
}

return 0;
}

int main()
{
char opcion;
int res;

if(WSAStartup(MAKEWORD(2,2), &wsa))
        return error();

std::cout << "Iniciando LordPakus WebServer" << std::endl;

res = Server();

if(res)
return res;

    WSACleanup();
system("PAUSE");
return 0;
}

Espero que os haya gustado. Para probarlo solo debéis arrancar vuestro navegador y en la ruta ponerle 127.0.0.1:8080. Ya vereis los resultados.

Nos vemos

0 comentarios :

Publicar un comentario

Entradas populares