当前位置:   article > 正文

http网络服务器

http网络服务器

wwwroot(目录)/index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>比特就业课</title>
  7. </head>
  8. <body>
  9. <h3>这是一个Linux课程</h3>
  10. <p>我是一个Linux的学习者,我正在进行http的测试工作!!!</p>
  11. </body>
  12. </html>

Makefile

  1. HttpServer:HttpServer.cc
  2. g++ -o HttpServer HttpServer.cc -std=c++11
  3. .PHONY:clean
  4. clean:
  5. rm -f HttpServer

Log.hpp

  1. #pragma once
  2. #include <iostream>
  3. #include <string>
  4. #include <cstdarg>
  5. #include <cstdio>
  6. #include <ctime>
  7. #define DEBUG 0
  8. #define NORMAL 1
  9. #define WARNING 2
  10. #define ERROR 3
  11. #define FATAL 4
  12. const char *gLevelMap[5] = {"DEBUG", "NORMAL", "WARNING", "ERROR", "FATAL"};
  13. #define LOGFILE "./threadpool.log"
  14. void logMessage(int level, const char *format, ...)
  15. {
  16. char stdBuffer[1024]; // 标准部分
  17. time_t timestamp = time(nullptr);
  18. struct tm *time = localtime(&timestamp);
  19. snprintf(stdBuffer, sizeof stdBuffer, "[%s][%ld]", gLevelMap[level], timestamp);
  20. char logBuffer[1024]; // 自定义部分
  21. va_list args;
  22. va_start(args, format);
  23. vsnprintf(logBuffer, sizeof(logBuffer), format, args); // 使用 vsnprintf 而不是 vsprintf
  24. va_end(args);
  25. //FILE* fp=fopen(LOGFILE,"a");
  26. //打印到显示器
  27. printf("%s %s\n", stdBuffer, logBuffer);
  28. // 打印到指定文件
  29. //fprintf(fp,"%s%s\n",stdBuffer,logBuffer);
  30. //fclose(fp);
  31. }

Sock.hpp

  1. #pragma once
  2. #include <iostream>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <string.h>
  6. #include <arpa/inet.h>
  7. #include <netinet/in.h>
  8. #include <string>
  9. #include <sys/wait.h>
  10. #include "Log.hpp"
  11. #include <memory>
  12. class Sock
  13. {
  14. private:
  15. const static int gbacklog = 20;
  16. public:
  17. Sock() {}
  18. int Socket()
  19. {
  20. int listensock = socket(AF_INET, SOCK_STREAM, 0);
  21. if (listensock < 0)
  22. {
  23. logMessage(FATAL, "create socket error,%d:%s", errno, strerror(errno));
  24. exit(2);
  25. }
  26. logMessage(NORMAL, "create socket success, listensock: %d", listensock);
  27. return listensock;
  28. }
  29. void Bind(int sock, uint16_t port, std::string ip = "0.0.0.0")
  30. {
  31. struct sockaddr_in local;
  32. memset(&local, 0, sizeof(local));
  33. local.sin_family = AF_INET;
  34. local.sin_port = htons(port);
  35. inet_pton(AF_INET, ip.c_str(), &local.sin_addr);
  36. // local.sin_addr.s_addr = _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());
  37. if (bind(sock, (const sockaddr *)&local, sizeof(local)) < 0)
  38. {
  39. logMessage(FATAL, "bind error, %d:%s", errno, strerror(errno));
  40. exit(3);
  41. }
  42. }
  43. void Listen(int sock)
  44. {
  45. if (listen(sock, gbacklog) < 0)
  46. {
  47. logMessage(FATAL, "listen error, %d:%s", errno, strerror(errno));
  48. exit(4);
  49. }
  50. logMessage(NORMAL, "listen server success");
  51. }
  52. int Accept(int listensock, std::string *ip, uint16_t *port)
  53. {
  54. struct sockaddr_in src;
  55. memset(&src, 0, sizeof(src));
  56. socklen_t len = sizeof(src);
  57. int servicesock = accept(listensock, (struct sockaddr *)&src, &len);
  58. if (servicesock < 0)
  59. {
  60. logMessage(ERROR, "accept error,%d:%s", errno, strerror(errno));
  61. return -1;
  62. }
  63. if (port)
  64. *port = ntohs(src.sin_port);
  65. if (ip)
  66. *ip = inet_ntoa(src.sin_addr);
  67. return servicesock;
  68. }
  69. bool Connect(int sock, const std::string &server_ip, const uint16_t &server_port)
  70. {
  71. struct sockaddr_in server;
  72. memset(&server, 0, sizeof(server));
  73. server.sin_family = AF_INET;
  74. server.sin_port = htons(server_port);
  75. server.sin_addr.s_addr = inet_addr(server_ip.c_str());
  76. if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == 0)
  77. return true;
  78. else
  79. return false;
  80. }
  81. ~Sock()
  82. {
  83. }
  84. };

Usage.hpp

  1. #pragma once
  2. #include <iostream>
  3. void Usage(const char *args)
  4. {
  5. std::cout << "\nUsage: " << args << " port" << std::endl;
  6. }

Util.hpp

  1. #pragma once
  2. #include <iostream>
  3. #include <vector>
  4. class Util
  5. {
  6. public:
  7. static void cutString(const std::string &s, const std::string &sep, std::vector<std::string> *out)
  8. {
  9. std::size_t start = 0;
  10. while (start < s.size())
  11. {
  12. auto pos = s.find(sep, start);
  13. if (pos == std::string::npos)
  14. {
  15. break;
  16. }
  17. std::string sub = s.substr(start, pos - start);
  18. out->push_back(sub);
  19. start += sub.size();
  20. start += sep.size();
  21. }
  22. if (start < s.size())
  23. out->push_back(s.substr(start));
  24. }
  25. };

HttpServer.hpp

  1. #pragma once
  2. #include <iostream>
  3. #include "Sock.hpp"
  4. #include <functional>
  5. #include <unistd.h>
  6. class HttpServer
  7. {
  8. public:
  9. using func_t = std::function<void(int)>;
  10. public:
  11. HttpServer(uint16_t port, func_t func)
  12. : _port(port), _func(func)
  13. {
  14. _listensock = sock.Socket();
  15. sock.Bind(_listensock, _port);
  16. sock.Listen(_listensock);
  17. }
  18. void Start()
  19. {
  20. signal(SIGCHLD, SIG_IGN);
  21. while (true)
  22. {
  23. std::string clientIp;
  24. uint16_t clientPort;
  25. int sockfd = sock.Accept(_listensock, &clientIp, &clientPort);
  26. if (sockfd == -1)
  27. {
  28. continue;
  29. }
  30. if (fork() == 0)
  31. {
  32. close(_listensock);
  33. _func(sockfd);
  34. close(sockfd);
  35. exit(0);
  36. }
  37. close(sockfd);
  38. }
  39. }
  40. ~HttpServer()
  41. {
  42. if (_listensock >= 0)
  43. {
  44. close(_listensock);
  45. }
  46. }
  47. private:
  48. int _listensock;
  49. uint16_t _port;
  50. Sock sock;
  51. func_t _func;
  52. };

HttpServer.cc

  1. #include <iostream>
  2. #include "HttpServer.hpp"
  3. #include <memory>
  4. #include "Usage.hpp"
  5. #include <unistd.h>
  6. #include "Util.hpp"
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <fstream>
  11. #define ROOT "./wwwroot"
  12. #define HOMEPAGE "index.html"
  13. void HandlerHttpRequest(int sockfd)
  14. {
  15. // 1.读取请求
  16. char buffer[1024];
  17. int s = read(sockfd, buffer, sizeof buffer);
  18. if (s > 0)
  19. {
  20. buffer[s] = 0;
  21. // std::cout << buffer << "--------------------" << std::endl;
  22. }
  23. std::vector<std::string> vline;
  24. Util::cutString(buffer, "\n", &vline);
  25. std::vector<std::string> vblock;
  26. Util::cutString(vline[0], " ", &vblock);
  27. std::string file = vblock[1];
  28. std::string target = ROOT;
  29. //默认首页
  30. if (file == "/")
  31. file = "/index.html";
  32. target += file;
  33. std::cout << target << std::endl;
  34. std::string content;
  35. std::ifstream in(target);
  36. if (in.is_open())
  37. {
  38. std::string line;
  39. while (std::getline(in, line))
  40. {
  41. content += line;
  42. }
  43. in.close();
  44. }
  45. // for (auto &iter : vblock)
  46. // {
  47. // std::cout << iter << "\n"
  48. // << std::endl;
  49. // }
  50. // 2.试着构建一个http的响应
  51. std::string HttpResponse;
  52. if (content.empty())
  53. {
  54. HttpResponse = "HTTP/1.1 404 NotFound\r\n";
  55. }
  56. else
  57. HttpResponse = "HTTP/1.1 200 OK\r\n";
  58. HttpResponse += "\r\n";
  59. HttpResponse += content;
  60. send(sockfd, HttpResponse.c_str(), HttpResponse.size(), 0);
  61. }
  62. int main(int argc, char *argv[])
  63. {
  64. if (argc != 2)
  65. {
  66. Usage(argv[0]);
  67. exit(0);
  68. }
  69. std::unique_ptr<HttpServer> httpserver(new HttpServer(atoi(argv[1]), HandlerHttpRequest));
  70. httpserver->Start();
  71. return 0;
  72. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/731698
推荐阅读
相关标签
  

闽ICP备14008679号