{"id":979,"date":"2025-02-02T17:44:42","date_gmt":"2025-02-02T22:44:42","guid":{"rendered":"https:\/\/80bits.blog\/?p=979"},"modified":"2025-02-02T17:44:43","modified_gmt":"2025-02-02T22:44:43","slug":"servidor-simple-http-1-1-en-lenguaje-c","status":"publish","type":"post","link":"https:\/\/80bits.blog\/index.php\/2025\/02\/02\/servidor-simple-http-1-1-en-lenguaje-c\/","title":{"rendered":"Servidor simple HTTP 1.1 en lenguaje C"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Esta publicaci\u00f3n es simplemente un c\u00f3digo de prueba para crear un servidor http rest en el lenguaje C, extremadamente sencillo version 1.1. Ya que este protocolo se basa en modo texto y es f\u00e1cil de implementar sin usar dependencias extras.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Diferencias entre http 1.1 y http 2<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Formato de transmisi\u00f3n:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/1.1<\/em> utiliza un formato basado en texto, lo que facilita la lectura y depuraci\u00f3n pero introduce cierta ineficiencia en el procesamiento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/2<\/em> emplea un formato binario, lo que reduce la sobrecarga de an\u00e1lisis y permite una transmisi\u00f3n de datos m\u00e1s r\u00e1pida y compacta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <strong>Multiplexaci\u00f3n de conexiones:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/1.1<\/em> procesa las solicitudes de forma secuencial o mediante t\u00e9cnicas de pipelining que, en algunos casos, pueden provocar bloqueos (head-of-line blocking).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/2<\/em> permite la multiplexaci\u00f3n, enviando m\u00faltiples streams de datos de forma simult\u00e1nea sobre una \u00fanica conexi\u00f3n, eliminando as\u00ed los bloqueos y optimizando el uso del canal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <strong>Compresi\u00f3n de cabeceras:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/1.1<\/em> env\u00eda las cabeceras de cada solicitud y respuesta sin compresi\u00f3n, lo que puede resultar redundante y aumentar el tama\u00f1o de los datos transmitidos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/2<\/em> incorpora la compresi\u00f3n de cabeceras mediante el algoritmo HPACK, reduciendo el volumen de informaci\u00f3n transferida, especialmente en comunicaciones repetitivas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <strong>Control de flujo y prioridad:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/1.1<\/em> carece de mecanismos avanzados para gestionar la prioridad de las solicitudes y el control del flujo de datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2022 <em>HTTP\/2<\/em> introduce sistemas para asignar prioridades a los streams y gestionar de manera din\u00e1mica el flujo de informaci\u00f3n, lo que mejora la eficiencia en la entrega de recursos seg\u00fan las necesidades del cliente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Estas mejoras t\u00e9cnicas en HTTP\/2 permiten una comunicaci\u00f3n m\u00e1s eficiente y r\u00e1pida entre cliente y servidor, aunque su complejidad aumenta en comparaci\u00f3n con la implementaci\u00f3n m\u00e1s sencilla de HTTP\/1.1.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3digo<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n\n#define PUERTO 8080\n#define TAM_BUFFER 4096\n\nint main(void) {\n    int fd_servidor, fd_cliente;\n    struct sockaddr_in direccion;\n    socklen_t longitud = sizeof(direccion);\n    char buffer&#91;TAM_BUFFER] = {0};\n\n    \/* Respuesta HTTP fija: status, cabeceras y cuerpo *\/\n    const char *respuesta_http =\n        \"HTTP\/1.1 200 OK\\r\\n\"\n        \"Content-Type: text\/plain\\r\\n\"\n        \"Content-Length: 13\\r\\n\"\n        \"\\r\\n\"\n        \"Hello, world!\";\n\n    \/* Creaci\u00f3n del socket *\/\n    fd_servidor = socket(AF_INET, SOCK_STREAM, 0);\n    if (fd_servidor == -1) {\n        perror(\"Error al crear el socket\");\n        exit(EXIT_FAILURE);\n    }\n\n    \/* Permitir reutilizar la direcci\u00f3n y puerto *\/\n    int opcion = 1;\n    if (setsockopt(fd_servidor, SOL_SOCKET, SO_REUSEADDR, &amp;opcion, sizeof(opcion)) &lt; 0) {\n        perror(\"Error en setsockopt\");\n        close(fd_servidor);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* Configuraci\u00f3n de la direcci\u00f3n del servidor *\/\n    direccion.sin_family = AF_INET;\n    direccion.sin_addr.s_addr = INADDR_ANY;\n    direccion.sin_port = htons(PUERTO);\n\n    \/* Enlazar el socket a la direcci\u00f3n y puerto especificados *\/\n    if (bind(fd_servidor, (struct sockaddr *)&amp;direccion, sizeof(direccion)) &lt; 0) {\n        perror(\"Error al hacer bind\");\n        close(fd_servidor);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* Poner el socket en modo escucha *\/\n    if (listen(fd_servidor, 3) &lt; 0) {\n        perror(\"Error en listen\");\n        close(fd_servidor);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"Servidor HTTP escuchando en el puerto %d\\n\", PUERTO);\n\n    \/* Bucle principal: aceptar y responder conexiones *\/\n    while (1) {\n        fd_cliente = accept(fd_servidor, (struct sockaddr *)&amp;direccion, &amp;longitud);\n        if (fd_cliente &lt; 0) {\n            perror(\"Error en accept\");\n            continue;  \/\/ Si falla una conexi\u00f3n, intenta con la siguiente\n        }\n\n        \/* Leer la solicitud HTTP (no se procesa realmente en este ejemplo) *\/\n        int bytes_leidos = read(fd_cliente, buffer, TAM_BUFFER - 1);\n        if (bytes_leidos > 0) {\n            buffer&#91;bytes_leidos] = '\\0';\n            printf(\"Solicitud recibida:\\n%s\\n\", buffer);\n        }\n\n        \/* Enviar la respuesta HTTP *\/\n        write(fd_cliente, respuesta_http, strlen(respuesta_http));\n\n        \/* Cerrar la conexi\u00f3n con el cliente *\/\n        close(fd_cliente);\n    }\n\n    \/* Cerrar el socket del servidor (nunca se alcanza en este ejemplo) *\/\n    close(fd_servidor);\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Compilar<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gcc httpapi.c -o httpapi.exe<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Como mencione el c\u00f3digo es extremadamente simple y solo sirve para ejemplificar el funcionamiento del protocolo 1.1<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta publicaci\u00f3n es simplemente un c\u00f3digo de prueba para crear un servidor http rest en el lenguaje C, extremadamente sencillo version 1.1. Ya que este protocolo se basa en modo texto y es f\u00e1cil de implementar sin usar dependencias extras. Diferencias entre http 1.1 y http 2 Formato de transmisi\u00f3n: \u2022 HTTP\/1.1 utiliza un formato [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":985,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[109,3,20,64,65],"tags":[79,110,78,114,111,73,113],"class_list":["post-979","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c","category-general","category-lenguajes-de-programacion","category-microservicios","category-sistemas-operativos","tag-api","tag-c-2","tag-http","tag-language","tag-lenguaje","tag-linux","tag-server"],"jetpack_featured_media_url":"https:\/\/80bits.blog\/wp-content\/uploads\/2025\/02\/cLanguageRobot.webp","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/979","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/comments?post=979"}],"version-history":[{"count":5,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/979\/revisions"}],"predecessor-version":[{"id":984,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/979\/revisions\/984"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media\/985"}],"wp:attachment":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media?parent=979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/categories?post=979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/tags?post=979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}