跳至正文

Http 服务器整好了

  • Linux

  上午9点钟起来,吃了饭就在弄昨天找到的一个Http服务器,总共只有200行不到的代码,很快就看完了,也理解了,唯一要到网上查阅一下的就是HTTP协议,大致能看懂一点,但是我想多看看。
  整了2个多小时,到近11点的时候就Ok了,把服务器弄好了,可以简单的浏览本地Html文件了,但是问题还有很多,比如子进程没有处理,让它们僵死了;还有这个程序只是用了一次读数据,内网倒不会有问题,外网的话,就不一定了,所以最好还是用循环的好。
  还有一些问题就是看Unix网络编程了,Unix网络编程前面的内容就是围绕着一个简单的程序进行讲解socket的,各种各样的问题,技术。
  这份代码以后我会重写,然后加入更多的元素,让它能够使用。服务器代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<fcntl.h>

#define BACKLOG 3
#define BUFSIZE 10244

char not_found =
    "HTTP/1.1 404 Not Found\r\n" "Content-Type: text/html\r\n"
    "Content-Length: 40\r\n" "\r\n"
    "<HTML><BODY>File not found</BODY></HTML>";
char bad_request =
    "HTTP/1.1 400 Bad Request\r\n" "Content-Type: text/html\r\n"
    "Content-Length: 39\r\n" "\r\n"
    "<h1>Bad Request (Invalid Hostname)</h1>";
/
char moved_permanently = 
     "HTTP/1.1 301 Moved Permanently\r\n"     "Content-Length: 147\r\n"        "Content-Type: text/html\r\n"       "Location: %s\r\n"          "\r\n"             "<head><title>Document Moved</title></head><body><h1>Object Moved</h1>This document may be found <a HREF="\" mce_HREF="\""%s\">here</a></body>"; 
/
char head_analysis(char p);
void read_send(const char p, char pbuf, int connfd);

int main(void)
{
        int listenfd;
        struct sockaddr_in servAddr;
        unsigned port = 80;

        printf("HTTP Server is starting at port %d\n", port);

        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if (listenfd == –1) {
                printf("Invalid socket!\n");
                return 1;
        }

        bzero(&servAddr, sizeof(servAddr));
        servAddr.sin_family = AF_INET;
        servAddr.sin_port = htons(port);
        servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

        printf("Server is listening…\n");
        if (bind(listenfd, (struct sockaddr ) &servAddr,
             sizeof(servAddr)) != 0) {
                close(listenfd);
                perror("Bind Error");
                return 1;
        }
        printf("Binding server to port %d successfully.\n", port);

        if (listen(listenfd, BACKLOG) != 0)
        {
                close(listenfd);
                perror("Listen error");
                return 1;
        }

        printf("Waiting client…\n");

        while (1) {
                struct sockaddr_in cliAddr;
                size_t cliAddrLen = sizeof(cliAddr);
                pid_t pid;
                char 
p = NULL,
                    from[20],
                    file_name[100] = "/home/zqynux/network/",
                    rcvbuf[1024], sendbuf[BUFSIZE];

                int connfd =
                    accept(listenfd, (struct sockaddr ) &cliAddr,
                           &cliAddrLen);
                if (connfd < 0) {
                        close(listenfd);
                        printf("accept error\n");
                        return 1;
                }

                pid = fork();
                if (pid == 0)
                {
                        close(listenfd);
                        strcpy(from, inet_ntoa(cliAddr.sin_addr));
                        printf("\n\nclient %s CONNECTED.\n", from);

                        if (recv(connfd, rcvbuf, sizeof(rcvbuf), 0) > 0) {
                                printf("%s\n", rcvbuf);
                                p = head_analysis(rcvbuf);
                        } else {
                                perror("Read Error");
                                exit(0);
                        }
                        if (p != NULL) {
                                strcat(file_name, p);
                                printf("FILE NAME :%s\n", file_name);
                                read_send(file_name, sendbuf, connfd);
                        } else{
                                printf("No default html\n");
                                send(connfd, bad_request,
                                     strlen(bad_request), 0);
                        }

                        close(connfd);
                        printf("DISCONNECTION TO CLIENT\n");
                        exit(0);
                } else if (pid > 0)
                        close(connfd);
                else
                        return 1;
        }

        close(listenfd);

        return 0;
}

char head_analysis(char p)
{
        char 
ptmp = p;

        if (strncmp(ptmp, "GET /"5) == 0) {
                ptmp += 5;
                while (ptmp != ‘ ‘)
                        ptmp++;
                
ptmp++ = ‘\0’;

                if (strncmp(ptmp, "HTTP/"5) == 0)
                        return p + 5;
                else
                        return NULL;
        }else
                return NULL;
}
void read_send(const char p, char pbuf, int connfd)
{
        int fd;
        size_t rdLen;
        fd = open(p, O_RDONLY);
        if (fd != –1) {
                send(connfd,
                     "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n",
                     strlen
                     ("HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"),
                     0);

                while ((rdLen = read(fd, pbuf, BUFSIZE)) > 0)
                        send(connfd, pbuf, rdLen, 0);

                printf("WRITE TO CLIENT FINISHED\n");
                close(fd);
        } else{
                send(connfd, not_found, strlen(not_found), 0);
                printf("FILE Not Find\n");
        }
}
  至于客户端就是浏览器。

发表评论

您的电子邮箱地址不会被公开。