美文网首页
最简单的http服务器

最简单的http服务器

作者: 超哥__ | 来源:发表于2019-04-03 12:40 被阅读0次

    Objective-C最简单的http服务器,只获取url请求部分
    稍作修改可以同时兼容linux

    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #define BUFFER_SIZE 4096
    #define PORT_BEG 2000
    #define PORT_END 2100
    char bundleid[128] = "com.lichao.test.test";
    
    void handle(char* ibuf, int ilen, char* obuf, int olen) {
        NSLog(@"%s", ibuf);
        strcpy(obuf, "ok");
    }
    
    void* start_server() {
        struct sockaddr_storage connector;
        struct sockaddr_in address;
        socklen_t addr_size = sizeof(connector);
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        for (int port = PORT_BEG; port < PORT_END; port++) {
            address.sin_port = htons(port);
            if (0 == bind(sock, (struct sockaddr *)&address, sizeof(address))) {
                NSLog(@"simpleserver:%s bind port %d", bundleid, port);
                listen(sock, 1);
                while (true) {
                    int accsock = accept(sock, (struct sockaddr *)&connector, &addr_size);
                    if (accsock > 0) {
                        char irawbuf[BUFFER_SIZE], orawbuf[BUFFER_SIZE], obuf[BUFFER_SIZE], ibuf[BUFFER_SIZE];
                        memset(ibuf, 0, BUFFER_SIZE);
                        memset(obuf, 0, BUFFER_SIZE);
                        memset(irawbuf, 0, BUFFER_SIZE);
                        memset(orawbuf, 0, BUFFER_SIZE);
                        if (recv(accsock, irawbuf, BUFFER_SIZE, 0) > 0) {
                            char* p1 = strchr(irawbuf, ' ') + 1;
                            char* p2 = strchr(p1, ' ');
                            memcpy(ibuf, p1, p2 - p1);
                            handle(ibuf, BUFFER_SIZE, obuf, BUFFER_SIZE);
                            // HTTP/1.1 404 Not Found\r\nContent-Length: 0
                            sprintf(orawbuf, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s", strlen(obuf), obuf);
                            send(accsock, orawbuf, strlen(orawbuf) + 1, 0);
                            close(accsock);
                        }
                    }
                }
                break;
            }
        }
        return 0;
    }
    
    int main(int argc, char * argv[]) {
        pthread_t tid;
        pthread_create(&tid, 0, (void* (*)(void*))start_server, 0);
    }
    

    测试:

    curl -s x.x.x.x:2000/test
    =>test
    

    同样的,如果要构造一个daemon类型的后台服务器,只需要做少许改动:

    #include <dlfcn.h>
    #include <netinet/in.h>
    #include <pthread.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <sys/sysctl.h>
    #include <sys/types.h>
    #include <sys/utsname.h>
    #include <unistd.h>
    
    #define MASTER
    
    #define MASTER_PORT 2000
    #define SLAVE_PORT_BEG 2001
    #define SLAVE_PORT_END 2100
    
    
    #define BUFFER_SIZE 65536
    
    void handle(char* ibuf, int ilen, char* obuf, int olen) {
        strcpy(obuf, ibuf);
    }
    
    void* start_server() {
        struct sockaddr_storage connector;
        struct sockaddr_in address;
        socklen_t addr_size = sizeof(connector);
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        int port = -1;
    #ifdef MASTER
        for (port = MASTER_PORT; port < MASTER_PORT + 1; port++) {
    #else
        for (port = SLAVE_PORT_BEG; port < SLAVE_PORT_END; port++) {
    #endif
            address.sin_port = htons(port);
            if (0 == bind(sock, (struct sockaddr *)&address, sizeof(address))) {
                NSLog(@"simpleserver:bind port %d", port);
                listen(sock, 1);
                while (true) {
                    int accsock = accept(sock, (struct sockaddr *)&connector, &addr_size);
                    if (accsock > 0) {
                        char irawbuf[BUFFER_SIZE], orawbuf[BUFFER_SIZE], obuf[BUFFER_SIZE], ibuf[BUFFER_SIZE];
                        memset(ibuf, 0, BUFFER_SIZE);
                        memset(obuf, 0, BUFFER_SIZE);
                        memset(irawbuf, 0, BUFFER_SIZE);
                        memset(orawbuf, 0, BUFFER_SIZE);
                        if (recv(accsock, irawbuf, BUFFER_SIZE, 0) > 0) {
                            char* p1 = strchr(irawbuf, ' ') + 2;
                            char* p2 = strchr(p1, ' ');
                            memcpy(ibuf, p1, p2 - p1);
                            handle(ibuf, BUFFER_SIZE, obuf, BUFFER_SIZE);
                            // HTTP/1.1 404 Not Found\r\nContent-Length: 0
                            sprintf(orawbuf, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s", strlen(obuf), obuf);
                            send(accsock, orawbuf, strlen(orawbuf) + 1, 0);
                            close(accsock);
                        }
                    }
                }
            }
        }
        exit(0);
    }
    
    int main(int argc, char **argv, char **envp) {
        pid_t ppid = getpid();
        pid_t p = fork();
        if (p == 0) { // child process
            kill(ppid, SIGKILL); // 变成daemon
            ppid = getpid();
            p = fork();
            if (p == 0) {
                kill(ppid, SIGKILL);
                pthread_t tid;
                pthread_create(&tid, 0, (void* (*)(void*))start_server, 0);
                pthread_detach(tid);
                getchar();
            }   
        } 
        sleep(1000);
    }
    

    相关文章

      网友评论

          本文标题:最简单的http服务器

          本文链接:https://www.haomeiwen.com/subject/zviabqtx.html