HTTP 服务器程序

       1、 HTTP只有两类消息:HTTP请求消息,由客户机端(如浏览器)向服务器发送的消息,用于请求服务器提供某种类型的服务;HTTP响应消息,服务器接收到请求消息之后返回给客户端的信息,表明服务器所作出的回答。两种消息具有相同的格式,通常分为消息头和消息体两个部分。消息头一定要有,消息体是可选的。消息头部的首行有特殊的格式,首行的后面有多个头部标题字段行,也简称为消息标题。每个头部标题行由标题字段名和字段值组成,他们之间有“:”隔开,标题字段名不区分大小写。

    HTTP请求消息的一般格式:HTTP请求的头部细分为请求行和标题字段区域。头部请求行是HTTP请求报文的第一行,交代请求使用的方法,请求的目标,和HTTP的版本号。例:GET /index.html HTTP/1.1;HTTP请求的第二行起是头部的标题字段区域,可以安排一行或多行消息标题,常用字段有Accept   表示客户端期望接收的媒体类型,Host    表明请求资源所在的主机地址,Referer    用于记录客户端获得URL资源的地址,User-Agent   使用的用户代理,Connection    对TCP连接的处理方式。

     典型的HTTP请求消息:

    GET  /path/file.html HTTP/1.0

    User-Agent:HTTPTool/1.0

     Connection:Close

    HTTP响应消息的一般格式:HTTP响应消息由两大部分组成,消息头和消息体,两者之间使用一个空白行分开。消息头又可细分为响应的状态行和响应的标题字段,消息体是响应的实体数据。HTTP响应消息的第一行为状态行,由HTTP版本号、响应码和响应描述符文本构成,中间用空格相连。例:HTTP/1.1   200  ok。HTTP状态码分为5种类型:1xx       信息响应,表示接收到请求并且继续处理,2xx       处理成功响应,表示动作被成功接收、理解和接收、3xx      重定向响应,为了完成指定的动作,必须接受进一步处理,4xx     客户端错误,请求包含语法错误或者请求无法实现,5xx    服务器错误,服务器不能正确执行一个正确的请求。最常用的状态码有:

      200  OK:请求成功,并且被请求的资源将会在响应消息中返回。

      301  Moved Permanently:客户请求的对象已永久性迁移,新的URL在Location头中给出,浏览器会自动访问新的URL。

      302  Moved Temporarily:所请求的对象被暂时迁移

      400  Bad  Request:服务器无法理解客户端的请求

      404  Not  Found:服务器不存在所请求的文档。客户端在对该请求作出更改前不应再次向服务器重复发送该请求

      500  Server Error:服务器异常,不能完成客户的请求。

      505   HTTP Version Not Supported:服务器不支持所请求的HTTP协议版本

   HTTP响应可用的标题字段分为响应标题和实体标题两类:

      响应标题有:Location     表示请求被重定向的URL的实际位置,使用绝对URL,并在响应字段返回3xx的响应码

                           Server         用于告知客户端服务器端使用的www服务器软件名称及版本信息

                           WWW-Authenticate   告知客户端受限资源所在的区域和要求的认证方法,同时应返回401响应码

     实体标题有:Allow   告知客户机端他请求的资源所允许的请求方法

                          Content-Type   用于描述HTTP响应消息中所含有的实体数据的类型

                          Content-Length   用于描述消息内任何类型的实体数据长度

   2、程序主流程图:

ClientThread流程图:

3、具体代码注释:

       HTTPProtocol.h文件:

    #ifndef  _HTTPPROTOCOL_H
#define _HTTPPRPTOCOL_H
#pragma once
#include <WinSock2.h>

 #pragma comment( lib, "ws2_32.lib")
#define HTTPPORT  80
#define METHOD_GET 0
#define METHOD_POST 1
#define METHOD_HEAD 2

//响应码
#define HTTP_STATUS_OK                "200 OK"
#define HTTP_STATUS_CREATED            "201 Created"
#define HTTP_STATUS_ACCEPTED        "202 Accepted"
#define HTTP_STATUS_NOCONTENT        "204 No Content"
#define HTTP_STATUS_MOVEDPERM        "301 Moved Permanently"
#define HTTP_STATUS_MOVEDTEMP        "302 Moved Temporarily"
#define HTTP_STATUS_NOTMODIFIED        "304 Not Modified"
#define HTTP_STATUS_BADREQUEST        "400 Bad Request"
#define HTTP_STATUS_UNAUTHORIZED    "401 Unauthorized"
#define HTTP_STATUS_FORBIDDEN        "403 Forbidden"
#define HTTP_STATUS_NOTFOUND        "404 File can not fonund!"
#define HTTP_STATUS_SERVERERROR        "500 Internal Server Error"
#define HTTP_STATUS_NOTIMPLEMENTED    "501 Not Implemented"
#define HTTP_STATUS_BADGATEWAY        "502 Bad Gateway"
#define HTTP_STATUS_UNAVAILABLE        "503 Service Unavailable"

typedef struct REQUEST
{
    HANDLE   hExit;
    SOCKET   Socket;                    //请求的socket
    int       nMethod;                  //请求的使用方法
    DWORD     dwRecv;                    //收到的字节数
    DWORD      dwSend;                   //发送的字节数
    HANDLE     hFile;                    //请求连接的文件
    char      szFileName[_MAX_PATH];      //文件的相对路径
    char      postfix[10];                //存储扩展名
    char      StatuCodeReason[100];       //响应码
    bool      permitted;                   //用户权限判断
    char*     authority;                   //用户提供的认证信息
    char      key[1024];                   //正确认证信息

    void*    pHttpProtocol;                 //指向类CHttpProtocol的指针

}REQUEST,*PREQUEST;


#include  <map>
#include  <string>
using namespace std;
class CHttpProtocol
{
public:
    HWND   m_hwndDlg;
    SOCKET m_listenSocket;
    map<CString,char *>  m_typeMap;  //保存content-type和文件后缀的对应关系
    CWinThread* m_pListenThread;
    HANDLE m_hExit;

    static  HANDLE  None;             //标志是否有Client连接到服务器
    static  UINT  ClientNum;            //连接的Client数量
    static  CCriticalSection m_critSect;            //互斥变量

    CString  m_strRootDir;                 //web的根目录
    UINT     m_nPort;                      //服务器的端口号

    void CreateTypeMap();     //创建content-type和文件后缀map
    void  StopHttpSrv();       //关闭服务
    bool  StartHttpSrv();       //启动服务

    static  UINT  ListenThread(LPVOID  param);    //监听线程
    static  UINT  ClientThread(LPVOID  param);     //请求处理线程

    bool RecvRequest(PREQUEST pReq, LPBYTE pBuf, DWORD dwBufSize);
    int Analyze(PREQUEST pReq, LPBYTE pBuf);
    void SendHeader(PREQUEST pReq);
    int FileExist(PREQUEST pReq);
    void SendFile(PREQUEST pReq);
    bool SendBuffer(PREQUEST pReq, LPBYTE pBuf, DWORD dwBufSize);
    bool GetContenType(PREQUEST pReq, LPSTR type);
    CHttpProtocol(void);
    ~CHttpProtocol(void);
};

#endif _HTTPPROTOCOL_H

********************************************************************************************************************************

    HTTPProtocol.cpp文件:

#include "stdafx.h"
#include "HttpProtocol.h

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值