使用C++制作简单的web服务器(续)

增加功能:
1、从文件中读取网页并返回给客户端,而不是把网页代码写死在代码中。
局限:
1、还不能根据URL地址中的参数,访问指定页面
2、仍然是单线程


//*****************************************************************************

//@ProjectName      ZYhttpd

//@Description      my http server

//@Author           NicoleRobin

//@Date             2015/02/09

//*****************************************************************************

#include <cstdio>

#include <string>

#include <fstream>

#include <WinSock2.h>

using namespace std;

#define BUFFER_SIZE 1024

#define HOST "127.0.0.1"

#define PORT 81

#define HEADER "\

HTTP/1.1 200 OK\r\n\

Content-Type: text/html; charset=UTF-8\r\n\

Server: ZYhttp_v1.0.1\r\n\

Content-Length: %ld\r\n\r\n\

"

const string strPath = "index.html";

#pragma comment(lib, "WS2_32")

// get file size

long GetFileLength(string strPath);

// thread function

int main(int argc, char **argv)

{

    // define and init an server sockaddr

    sockaddr_in addrServer;

    addrServer.sin_family = AF_INET;

    addrServer.sin_addr.S_un.S_addr = INADDR_ANY;

    addrServer.sin_port = htons(PORT);

    // init socket dll

    WSADATA wsaData;

    WORD socketVersion = MAKEWORD(2, 0);

    if (WSAStartup(socketVersion, &wsaData) != 0)

    {

        printf("Init socket dll error!");

        exit(1);

    }

    // create socket

    SOCKET socketServer = socket(AF_INET, SOCK_STREAM, 0);

    if (SOCKET_ERROR == socketServer)

    {

        printf("Create socket error!");

        exit(1);

    }

    // bind server socket host

    if (SOCKET_ERROR == bind(socketServer, (LPSOCKADDR)&addrServer, sizeof(addrServer)))

    {

        printf("Bind server host failed!");

        exit(1);

    }

    // listen

    if (SOCKET_ERROR == listen(socketServer, 10))

    {

        printf("Listen failed!");

        exit(1);

    }

    while (true)

    {

        printf("Listening ... \n");

        sockaddr_in addrClient;

        int nClientAddrLen = sizeof(addrClient);

        SOCKET socketClient = accept(socketServer, (sockaddr*)&addrClient, &nClientAddrLen);

        if (SOCKET_ERROR == socketClient)

        {

            printf("Accept failed!");

            break;

        }

        char buffer[BUFFER_SIZE];

        memset(buffer, 0, BUFFER_SIZE);

        if (recv(socketClient, buffer, BUFFER_SIZE, 0) < 0)

        {

            printf("Recvive data failed!");

            break;

        }

        printf("Recv data : \n%s", buffer);

        /*

        // response

        memset(buffer, 0, BUFFER_SIZE);

        ifstream fin(strPath.c_str(), ios::in | ios::binary);

        if (fin.is_open())

        {

            char szTmp[512] = "";

            fin.read(szTmp, 511);

            sprintf_s(buffer, HEADER, GetFileLength(strPath), szTmp);

            if (send(socketClient, buffer, strlen(buffer), 0) < 0)

            {

                printf("Send data failed!");

                break;

            }

        }

        fin.close();

        */

        // response 

        // send header

        memset(buffer, 0, BUFFER_SIZE);

        sprintf_s(buffer, HEADER, GetFileLength(strPath));

        if (send(socketClient, buffer, strlen(buffer), 0) < 0)

        {

            printf("Send data failed!");

            break;

        }

        ifstream fin(strPath.c_str(), ios::in | ios::binary);

        if (fin.is_open())

        {

            memset(buffer, 0, BUFFER_SIZE);

            while (fin.read(buffer, BUFFER_SIZE - 1))

            {

                if (send(socketClient, buffer, strlen(buffer), 0) < 0)

                {

                    printf("Send data failed!");

                    break;

                }

                memset(buffer, 0, BUFFER_SIZE);

            }

            if (send(socketClient, buffer, strlen(buffer), 0) < 0)

            {

                printf("Send data failed!");

                break;

            }

        }

        fin.close();

        closesocket(socketClient);

    }

    closesocket(socketServer);

    WSACleanup();

    return 0;

}

long GetFileLength(string strPath)

{

    ifstream fin(strPath.c_str(), ios::in | ios::binary);

    fin.seekg(0, ios_base::end);

    streampos pos = fin.tellg();

    long lSize = static_cast<long>(pos);

    fin.close();

    return lSize;

    /*

    long lSize = 0;

    ifstream fin(strPath.c_str(), ios::in | ios::binary);

    char szBuf[1024*1000] = "";

    while (fin.read(szBuf, 1024 * 1000 - 1))

    {

        lSize += strlen(szBuf);

        memset(szBuf, 0, 1024*1000);

    }

    fin.close();

    lSize += strlen(szBuf);

    return lSize;

    */

}

演示图

以上所述就是本文对于使用C++实现简单web服务器的全部代码了,希望大家能够喜欢。