1. 程式人生 > >linux C學習之實現簡單的web伺服器

linux C學習之實現簡單的web伺服器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>

#define RECV_PORT    8000
#define QLEN        10
#define MAX_SIZE    1024

char browser_com_buf[256];
    
int mylisten (void)
{
    int listenfd;
    int err;
    socklen_t addrlen;
    struct sockaddr_in server_addr;
    char *address = "192.168.0.3";
    
    listenfd = socket ( AF_INET, SOCK_STREAM, 0 );   /*creat a new socket*/
    if ( listenfd < 0 )
    {
        printf ( "listen error\n" );
        return -1;
    }
    memset ( &server_addr, 0, sizeof ( server_addr ) );    
    server_addr.sin_family = AF_INET;    /*IPV4*/
    server_addr.sin_port = htons ( RECV_PORT );
    server_addr.sin_addr.s_addr = htonl ( INADDR_ANY );
    
    addrlen = sizeof ( server_addr );
    err = bind ( listenfd, ( struct sockaddr * )&server_addr, addrlen );
    if ( err < 0 )
    {
        printf ( "bind error\n" );
        return -2;
    }
    err = listen ( listenfd, QLEN );
    if ( err < 0 )
    {
        printf ( "listen error" );
        return -3;
    }
    return listenfd;
}

int myaccept ( int listenfd )
{
    int clientfd;
    int err;
    socklen_t addrlen;
    struct sockaddr_in client_addr;
    
    addrlen = sizeof ( client_addr );
    clientfd = accept ( listenfd, ( struct sockaddr * )&client_addr, &addrlen );
    if ( clientfd < 0 )
    {
        printf ( "accept error\n" );
        return -1;
    }
    return clientfd;
}

void browser_com_analysis ( char *com, char *buf )
{
    int i = 0;
    unsigned int flag = 0;
    char *locate;
    
    locate = strchr ( com, '/' );
    if ( locate == NULL )
    {
        printf ( "not find\n" );
        exit ( 1 );
    }
    else
    {
        while ( *locate != ' ' )
        {
            buf[i++] = *locate;
            locate++;
        }
        buf[i] = '\0';
    }
    //printf ( "%s\n", buf );
}

int state_estimat ( char *buf )
{
    int len;
    unsigned int flag = 0;
    int i = 0, j = 0;
    char buf1[256];
    char *image_style = ".jpg";
    char file_name[256] = { "/var/www" };
    struct stat statbuf;
    
    len = strlen ( buf );
    memset ( buf1, '\0', sizeof ( buf1 ) );
    while ( i < len )
    {
        if ( buf[i] == '.' )
        {
            flag = 1;
        }
        if ( flag == 1 )
        {
            if ( buf[i] == ' ' || buf[i] == '\n' )
            {
                break;
            }
            else
            {
                buf1[j++] = buf[i];
            }
        }
        i++;
    }
    //printf ( "%s%d\n", buf1, len );
    if ( len == 0 )
    {
        printf ( "http have not send comand\n" );
        exit ( 1 );
    }
    else if ( len == 1 )
    {
        return 1;
    }
    else if ( len > 1 )
    {
        strcat ( file_name, buf );
        stat ( file_name, &statbuf );
        if ( statbuf.st_mode == S_IXOTH )   //其他使用者具有可執行許可權
        {
            //如果具有可執行許可權,則執行該檔案,將結果傳送到瀏覽器上
            return 4;
        }
        else
        {
            //不具有可執行許可權則判斷圖片還是檔案
            if ( strcmp ( buf1, image_style ) == 0 )
            {
                return 2;    //瀏覽器請求的是圖片
            }
            return 3;    //瀏覽器請求的是檔案
        }
    }
}

int find_file ( char *buf, int clientfd )
{
    int state;
    char my_file_buf[65536 * 2];
    int n;
    char fault[] = { "HTTP/1.1 404 Not Found\nContent-Type: text/html\n<html><body>request file not found</body></html>\n\n" };
    char head[] = { "HTTP/1.1 200 OK\nContent-Type: text/html\n\n" };
    char head2[] = { "HTTP/1.1 200 OK\nContent-Type: image/jpg\n\n" };
    char head3[] = { "HTTP/1.1 200 OK\n\n" };
    char file_name[] = { "/var/www" };
    
    memset ( &my_file_buf, '\0', MAX_SIZE );
    state = state_estimat ( buf );
    if ( state == 1 )  //server send file to browser
    {
        int filefd;
        
        filefd = open ( "/var/www/index.html", O_RDWR );
        if ( filefd < 0 )
        {
            printf ( "find file failed\n" );
            write ( clientfd, fault, strlen ( fault ) );
            close ( clientfd );
        }
        else
        {
            n = read ( filefd, my_file_buf, MAX_SIZE );
            if ( n < 0 )
            {
                printf ( "read the root file failed\n" );
                exit ( 1 );
            }
            strcat ( head, my_file_buf );
            printf ( "%s", head );
            write ( clientfd, head, strlen ( head ) );
            close ( clientfd );  
        }
    }
    else if ( state == 2 )   
    {
        printf ( "picture\n" );
        int picture_fd;    
        int n;
        
        write ( clientfd, head2, strlen ( head2 ) );
        memset ( &my_file_buf, '\0', sizeof ( my_file_buf ) );
        strcat ( file_name, buf );
        picture_fd = open ( file_name, O_RDONLY );   //只讀開啟圖片檔案
        if ( picture_fd  < 0 )
        {
            printf ( "open picutre failed\n" );
            exit ( 1 );
        }
        n = read ( picture_fd, my_file_buf, sizeof ( my_file_buf ) );
        if ( n < 0 )
        {
            printf ( "read picutre data failed\n" );
            exit ( 1 );
        }
        write ( clientfd, my_file_buf, sizeof ( my_file_buf ) );
        close ( clientfd );
    }
    else if ( state == 3 )
    {
        printf ( "file\n" );
        int file_fd;
        int n;
        
        write ( clientfd, head, strlen ( head ) );
        memset ( &my_file_buf, '\0', sizeof ( my_file_buf ) );
        strcat ( file_name, buf );
        
        file_fd = open ( file_name, O_RDONLY );
        if ( file_fd < 0 )
        {
            printf ( "open picutre failed\n" );
            exit ( 1 );
        }
        n = read ( file_fd, my_file_buf, sizeof ( my_file_buf ) );
        if ( n < 0 )
        {
            printf ( "read file failed \n" );
            exit ( 1 );
        }
        write ( clientfd, my_file_buf, sizeof ( my_file_buf ) );
    }
    else if ( state == 4 )
    {
        printf ( "executable file\n" );
        pid_t pid;
    
        pid = fork ();
        if ( pid < 0 )
        {
            printf ( "creat child failed\n" );
            exit ( 1 );
        }
        else if ( pid > 0 )    //parent
        {
            int stateval;
            waitpid ( pid, &stateval, 0 );
            close ( clientfd );
        }
        else    //child
        {
            int err;
            char *argv[1];
            
            strcat ( file_name, buf );
            argv[1] = file_name;
            dup2 ( STDOUT_FILENO, clientfd );
            err = execv ( "/bin/bash", argv );
            if ( err < 0 )
            {
                printf ( "execut file failed\n" );
                exit ( 1 );
            }
            close ( clientfd );
        }
    }
}

int main ( int argc, char *argv[] )
{
    int listenfd, clientfd;
    int filefd, n;
    char recvbuf[MAX_SIZE];
    char data_buf[MAX_SIZE];
    
    listenfd = mylisten();
    if ( listenfd < 0 )
    {
        exit ( 0 );
    }
    
    printf ( "listening and listen fd is %d......\n", listenfd );
    while ( 1 )
    {
        clientfd = myaccept ( listenfd );
        printf ( "accept success......\n" );
        if ( clientfd < 0 )
        {
            exit ( 1 );
        }
        memset ( &recvbuf, '\0', MAX_SIZE );
        memset ( &data_buf, '\0', MAX_SIZE );
        n = read ( clientfd, recvbuf, MAX_SIZE );
        printf ( "read OK\n" );
        if ( n < 0 )
        {
            printf ( "read error\n" );
            exit ( 2 );
        }
        
        filefd = open ( "/tmp/read_html.txt", O_RDWR | O_CREAT | O_TRUNC );   //open o new file
        write ( filefd, recvbuf, n );  //save the http information
        browser_com_analysis ( recvbuf, data_buf );
        find_file ( data_buf, clientfd );
    }
    close ( clientfd );    
    
    return 0;
}

相關推薦

linux C學習實現簡單web伺服器

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h

python學習實現簡單的miniWeb伺服器

webServer部分: #!/usr/bin/venv python3 # coding: utf-8 import socket import multiprocessing import re import dynamic.WebFrame as WebFra

Linux C UDP Socket實現客戶與伺服器簡單通訊

在linux平臺下用c語言udp協議實現客戶與伺服器的簡單通訊與封裝的實現 一、伺服器端 1、新建CreateServer.c和CreateServer.h檔案,伺服器的建立程式碼在此實現,程式中封裝了建立TcpSocket和UdpSocket伺服器的方法,

c語言實現簡單web伺服器

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

使用linux-c編程實現簡單的ls命令

使用c實現ls命令使用Linux—c編程實現簡單的ls命令 具體代碼如下: 加載的頭文件有stdio.h,sys/types.h,dirent.h,unistd.h,sys/stat.h,fcntl.h,string.h等。 void main(int argc,char **argv){

機器學習實現簡單的神經網路

機器學習的本質是模擬人的神經元對資訊的處理方法。可以將神經元看成是一個簡單的帶有二進位制輸出功能的邏輯電路門,多種電訊號可以從神經元的樹突部分傳入,然後對多個傳入的電訊號進行結合,統一地運算,得到的唯一的電訊號會通過神經元的軸突–>神經末梢傳遞給其他神經元

利用xinetd實現簡單web伺服器(映象站)

瀏覽效果: linux伺服器安裝xinetd後,在/etc/xinetd.d/目錄下建立xhttpd檔案,並輸入內容: service xhttpd { socket_type = stream protocol = tcp wait = no

自己開發簡單web伺服器一(C++開源庫websocketpp實現

簡要 Web伺服器主要處理的是HTTP請求(這裡忽略HTTPS),HTTP協議建立在TCP上。如果自己實現,無非就是網路程式設計(socket接受、傳送),資料解析(HTTP欄位解析),返回HTTP協議字串給客戶端等。說起來簡單,要做到跨平臺和高效,不得不介紹幾個有名的開源

Linux學習路 -- 簡單日常使用命令

簡單 日誌 reboot logs netstat oca yum a.out mysql tail -f catalina.out #在 logs 下面查看日誌( -f 實時查看) rm -rf /var/log/httpd/access

c語言實現簡單web服務器

tps gate choices found lte expect inf tro condition 1http簡單介紹http超文本傳輸協議:host主機地址:port端口/urlhost會被DNS服務器 解析成IP地址,所以有時候可以直接用域名,http默認訪問80端

java學習實現一個簡單的ArrayList

package thread1; /** * 實現一個簡單的ArrayList * * @Title: uminton */ public class SimpleArrayList<T> { //陣列中元素的大小 private Intege

Jetty實戰 嵌入式執行Jetty實現簡單檔案伺服器

                本文連結:http://blog.csdn.net/kongxx/article/details/7224423對於嵌入式執行Jetty,可以通過簡單的一些程式碼實現一個簡單的檔案伺服器的功能,如下:package com.google.code.garbagecan.jett

go語言實現簡單web伺服器

go語言讓web伺服器實現和部署變得異常簡潔.終於可以拋開亂七八糟的專案結構和體積龐大的IDE,一窺其基本原理. 首先是一個簡單的伺服器實現程式碼,如果是GET請求,則回送一條This is a GET request訊息,如果是POST請求,則解析POST請

菜鳥的C#學習旅——多型的實現途徑

目錄 一、定義 二、虛方法: 三、抽象類與抽象方法: 四、介面實現: 五、總結: 一、定義 多型:在面嚮物件語言中,介面的多種不同實現方式即為多型 多型性就是指在程式執行時,執行的雖然是一個呼叫方法的語句,卻可以根據派生類物件的型別的不同完成方法不同的具體實現

一個簡單web伺服器的java實現

一個簡單的web伺服器在不考慮其效能及健壯性的情況下,通常只需實現的功能包括伺服器的啟動,它用於監聽某一個埠,接收客戶端發來的請求,並將響應結果返回給客戶端。本文將介紹一個簡單web伺服器的實現原理,它本身只能處理某個目錄下的靜態資原始檔(文字、圖片等)。採用java

python uwsgi實現簡單web伺服器(8程式碼)

python uwsgi實現的簡單web伺服器,一共用了8行程式碼。 先說一下web領域的幾個概念,主要是舉例: web伺服器:apache、iis、nginx等。 web應用伺服器:tomcat、

C++學習多型篇(虛擬函式和虛解構函式的實現原理--虛擬函式表)

通過下面的程式碼來說明: #include <iostream> #include <stdlib.h> #include <string> using namespace std; /**  *  定義動物類:Animal  *  成員

學習Linux C程式設計語句

一、空語句 由分號“;”構成,作用:1.消耗cpu,起延時作用 2.使程式結構清楚,可讀性好 二、基礎語句 1.表示式+; 2.函式名+; 三、語句if     注意:1.不可將布林量直接與TRUE、FALSE或者1、0作比較,例如VC++將TRUE定義為1,而VB將TUR

自己開發簡單web伺服器二(Node.js實現

Node.js 剛接觸Node.js沒多久,試用了一下,輕輕鬆鬆幾行程式碼就可以實現一個簡單的HTTP伺服器,開發起來的確比其他語言快多了。 Node.js是一個開源的JavaScript庫,可以跨平臺執行在Windows、Linux、Mac上。JS解析庫用的是大名鼎鼎的G

學習Linux C程式設計語句 問題-break和continue

break和continue都是用來控制迴圈結構的,主要是停止迴圈。 1.break 有時候我們想在某種條件出現的時候終止迴圈而不是等到迴圈條件為false才終止。 這是我們可以使用break來完成。 break用於完全結束一個迴圈,跳出迴圈體執行迴圈後面的語句。