计算机网络基础

 

HTTP实现

HTTP实现包括server端和client端,其中server端用于处理client端发送的请求

server.h

HTTP需要设置server最大缓存大小、允许的最大连接数量、当前client传递的套接字、以及client传送的请求信息、客户端地址的内存长度,以及发送信息给client

  #include <WinSock2.h>
  #include <WS2tcpip.h>
  #pragma once
  // 最大传输字符数量 10M
  #if !MAX_CONNECT_CHAR_BUFFER
  #define MAX_CONNECT_CHAR_BUFFER 10485760  
  #endif

  class server{
    public:

    // c:ipv4 port:请求端口
      server(const char* c, u_short port);
      server(const char* c, u_short port, int type);

    // 监听 允许监听的最大num数量
    void listen(int num);

    ~server();

    // 套接字 WinSock2.h
    SOCKET s;
    
    // 当前客户端的请求信息 WS2tcpip.h
    SOCKADDR_IN serverIn;

    // 链接的客户端地址信息的内存长度
    int nowClientAddrLen;

    // 当前请求的缓存内容
    char buffer[MAX_CONNECT_CHAR_BUFFER];

    // 往客户端发送字符串
    BOOL send(string s);
    BOOL send(string s, SOCKET s2);

    BOOL allSend(string s);
    int errorInt;
    BOOL waitUDP(SOCKET s, char* bufer, const char* host, int port, int flags=0);
    vector<SOCKET> clientArr;
    vector<int> socketIndex;
    BOOL createThread(int index);
    string nowClientMsg;
  };

server.cpp

  #include "server.h"

  server::server(const char* c, u_short port){
    memset(&serverIn, 0, sizeof(serverIn));
    serverIn.sin_family = AF_INET;
    serverIn.sin_port = htons(port);
    serverIn.sin_addr.S_un.S_addr = inet_addr(c);
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  };

  server::server(const char* c, u_short port, int type){
    memset(&serverIn, 0, sizeof(serverIn));
    serverIn.sin_family = AF_INET;
    serverIn.sin_port = htons(port);
    serverIn.sin_addr.S_un.S_addr = inet_addr(c);
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  };

  void server::listen(int num){

  };

  BOOL server::allSend(string s){
    for(unsigned int i = 0; i< clientArr.size(); i++){
      this.send(s, clientArr[i]);
    }
  };

  BOOL server::send(string s, SOCKET s2){
    errorInt =::send(s2, s.c_str(), s.length() +1 , 0);
    if(errorInt == SOCKET_ERROR){
      return FLASE;
    }else{
      return TRUE;
    }
  };

  BOOL server::send(string s) {
    return this->send(s, nowClient);
  };

  BOOL server::createThread(int index){
    HANDLE ev = WSACreateEvent();
    WSAEventSelect(this->clientArr[index], ev, FD_ACCEPT | FD_CLOSE);
    // 1:数组中时间对象句柄的数目,此处为1
    // &ev 指向一个事件对象句柄数组的指针
    // TRUE:指定等待类型,如果为TRUE,则需要所有事件对象同时有信号,如果为FALSE,需要任意事件对象有信号时返回,返回值指出哪个事件对象造成函数返回
    // INFINITE:指定超时时间间隔,当超时间隔到,函数即返回
    // 一般设置为TRUE
    WSAWaitForMultipleEvents(1, &ev, TRUE, INFINITE, FALSE);
  };

  void server::listen(int num){
    
  }

  server::~server(){

  }

oMap.h & oMap.cpp

用于client的属性封装类

  #pragma once
  template <class key, class value>
  class oMap{
    public:
      oMap();
      ~oMap();
      bool set(key, value);
      bool find(key);
      string toString();
      value get(key);
      value& operator [](key);
      BOOL foreach(void(*) (int, value, key));
    public:
      vector<key> _key;
      vector<value> _value;
  };

  template <class key, class value>
  oMap::oMap(){

  }

helpClass.h

定义了client的static方法,其中实现了get方法

  #pragma once
  class helpClass{

    public:
    helpClass();
    ~helpClass();

  // 拆分字符串
  static vector<string> split(string s, string s2);

  // 获取请求头
  static oMap<string, string> getRequestHead(string request);

  // 获取默认的响应头
  static string getResponseHead(string request, int status, string statusMsg, oMap<string, string>headObj);

  // 获取系统时间
  static string getTime();

  // 获取完整的请求文件地址
  static string getFileUrl(string url,string methodType, oMap<string, string>getMap);

  // 获取文件字符集
  static string helpClass::getFileCharset(string s);

  // 获取minitype
  static string getMINItype(string path);

  // 字符串转码方法
  static LPWSTR user_stringToLPWSTR(string orig);
  static string user_LPWSTRTostring(LPWSTR lpw);
  static LPCSTR user_LPWSTRToLPCSTR(LPWSTR lpw);
  static LPWSTR user_LPCSTRToLPWSTR(LPCSTR lpc);

  // client入口函数
  static void handleRequestLine(SOCKET& s, string request);

  // 处理get请求
  static void helpClass::methodGetHandle(SOCKET& s, string request, oMap<string, string> getMap);

  // 读取文件的方法
  static int readFile(string filepath, string& content);


  };
  namespace METHOD_TYPE {
    const string uHTTP_GET = "GET";
    const string uHTTP_POST = "POST";
    const string uHTTP_OPTIONS = "OPTIONS";
    const string uHTTP_DELETE = "DELETE";
    const string uHTTP_PUT = "PUT";
  };


helpClass.cpp

  #include "helpClass.cpp"

  #define DEFAULT_PATH ""

  helpClass::helpClass(){}
  helpClass::~helpClass(){}

  // 字符串转换算法的实现
  LPWSTR helpClass::user_stringToLPWSTR(string orig){
    int leg = orig.length();
    LPWSTR d = malloc(sizeof(LPWSTR)* (leg+1));
    memset(d, 0, sizeof(LPWSTR)* (leg+1));

    // 编码方式、offset、char*、length、LPWSTR、size
    MultiByteToWideChar(CP_ACP, 0, orig.c_str(), lng, d, lng * sizeof(PWSTR));
    return d;
  }
  string helpClass::user_LPWSTRTostring(LPWSTR lpw) {
    int lng = lstrlenW(lpw);
    LPSTR d = (LPSTR)malloc(sizeof(PSTR)*lng);
    memset(d, 0, sizeof(PSTR)*lng);


    WideCharToMultiByte(CP_OEMCP, NULL, lpw, -1, d, sizeof(PSTR)*lng, NULL, FALSE);
    string q = d;
    return q;
  }
  LPCSTR helpClass::user_LPWSTRToLPCSTR(LPWSTR lpw) {
    string s1 = helpClass::user_LPWSTRTostring(lpw);
    return (s1.c_str());
  }


  // 拆分字符串
  vector<string> helpClass::split(string s, string s2){
    
  }

  // 获取请求头
   oMap<string, string> helpClass::getRequestHead(string request);

  // 获取默认的响应头
  static string getResponseHead(string request, int status, string statusMsg, oMap<string, string>headObj);

  // 获取系统时间
  static string getTime();

  // 获取完整的请求文件地址
  static string getFileUrl(string url,string methodType, oMap<string, string>getMap);

  // 获取文件字符集
  static string helpClass::getFileCharset(string s);

  // 获取minitype
  static string getMINItype(string path);

  // 字符串转码方法
  static LPWSTR user_stringToLPWSTR(string orig);
  static string user_LPWSTRTostring(LPWSTR lpw);
  static LPCSTR user_LPWSTRToLPCSTR(LPWSTR lpw);
  static LPWSTR user_LPCSTRToLPWSTR(LPCSTR lpc);

  // client入口函数
  static void handleRequestLine(SOCKET& s, string request);

  // 处理get请求
  static void helpClass::methodGetHandle(SOCKET& s, string request, oMap<string, string> getMap);

  // 读取文件的方法
  static int readFile(string filepath, string& content);


  //