ffhttpd.c

程序代码:
#include <stdlib.h>  
#include <stdio.h >  
#include <string.h>
#ifdef __WIN32__
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define  closesocket close
#endif
#define FFHTTPD_SERVER_PORT     8080
#define FFHTTPD_MAX_CONNECTION  100
static char *g_ffhttpd_head = 
"HTTP/1.1 200 OK\r\n"
"Server: ffhttpd/1.0.0\r\n"
"Content-Type: text/html\r\n"
"Content-Length: %d\r\n"
"Accept-Ranges: bytes\r\n"
"Connection: close\r\n\r\n";
static int file_load(char *path, char **data)
{
    char *buffer   = NULL;
    int   filesize = 0;
    FILE *fp       = NULL;
    if (!path || !data) return 0;
    fp = fopen(path, "rb");
    if (fp) {
        fseek(fp, 0, SEEK_END);
        filesize = ftell(fp);
        fseek(fp, 0, SEEK_SET);
        buffer = malloc(filesize);
        if (buffer) fread(buffer, filesize, 1, fp);
        fclose(fp);
    }
    *data = buffer;
    return filesize;
}
static void file_free(char **data)
{
    if (data) {
        free(*data);
        *data = NULL;
    }
}
static void parse_string(char *str, char *path, int size)
{
    char *src_start = NULL;
    char *src_end   = NULL;
    char *dst_end   = path + size;
    src_start = strstr(str, "GET /");
    if (src_start) {
        src_start += 5;
        src_end = strstr(src_start, " ");
        while (src_start < src_end && path < dst_end) *path++ = *src_start++;
        if (path == dst_end) path--;
    }
    *path = 0;
}
int main(void)
{
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    int    server_fd, conn_fd, addrlen, length;
    char   buffer[1024], path[1024], *filedata;
#ifdef __WIN32__
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        exit(1);
    }
#endif
    server_addr.sin_family      = AF_INET;
    server_addr.sin_port        = htons(FFHTTPD_SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        printf("failed to open socket !\n");
        exit(1);
    }
    if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        printf("failed to bind !\n");
        exit(1);
    }
    if (listen(server_fd, FFHTTPD_MAX_CONNECTION) == -1) {
        printf("failed to listen !\n");
        exit(1);
    }
    addrlen = sizeof(client_addr);
    while (1) {
        conn_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addrlen);
        if (conn_fd == -1) {
            printf("failed to accept !\n");
            continue;
        }
        length = recv(conn_fd, buffer, sizeof(buffer), 0);
        buffer[length] = 0;
        printf(buffer); fflush(stdout);
        parse_string(buffer, path, sizeof(path));
        if (!path[0]) strcpy(path, "index.html");
        length = file_load(path, &filedata);
        snprintf(buffer, sizeof(buffer), g_ffhttpd_head, length);
        if (1     ) send(conn_fd, buffer, strlen(buffer), 0);
        if (length) send(conn_fd, filedata, length, 0);
        file_free(&filedata);
        closesocket(conn_fd);
    }
    closesocket(server_fd);
#ifdef __WIN32__
    WSACleanup();
#endif
}