实现一个简单的Http服务器,基于windows 平台。 总共五个文件 : HttpServer.hpp、HttpServer.cpp、Utils.hpp、Utils.cpp、main.cpp
Utils.hpp
#include <vector>
#include <string>
#include <iostream>
using namespace std;
void splitStr(const string& s, vector<string>& v, const string& c);
Utils.cpp
#include "Utils.hpp"
void splitStr(const string& s, vector<string>& v, const string& c) {
string::size_type pos1, pos2;
pos2 = s.find(c);
pos1 = 0;
while(string::npos != pos2) {
v.push_back(s.substr(pos1, pos2 - pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
}
if(pos1 != s.length())
v.push_back(s.substr(pos1));
}
HttpServer.hpp
#pragma once
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
class HttpServer {
public:
HttpServer();
~HttpServer();
bool start(unsigned short port);
void run();
void stop();
private:
bool init();
DWORD WINAPI clientThreadFun(LPVOID lpThreadParameter);
bool _isExit = false;
unsigned short _port = 8892;
SOCKET _listenSocket = INVALID_SOCKET;
bool getRequest(string str);
std::string getResponse(string connectLen);
};
HttpServer.cpp
#include "HttpServer.hpp"
#include <thread>
#include <regex>
#include "Utils.hpp"
using namespace std;
HttpServer::HttpServer() {
WSADATA wd;
if(0 != WSAStartup(MAKEWORD(2, 2), &wd)) {
cout << "WSAStartup error: " << WSAGetLastError() << endl;
return;
}
cout << "WSAStartup success: " << endl;
}
HttpServer::~HttpServer() {
WSACleanup();
}
bool HttpServer::start(unsigned short port) {
_isExit = false;
_port = port;
if(!init()) {
cout << "httpserver start error" << endl;
}
thread sth(&HttpServer::run, this);
sth.detach();
cout << "httpserver start success" << endl;
return true;
}
void HttpServer::run() {
while(!_isExit) {
sockaddr_in addrClient;
int len = sizeof(sockaddr_in);
SOCKET c = accept(_listenSocket, (SOCKADDR*)&addrClient, &len);
if(INVALID_SOCKET != c) {
thread sth(&HttpServer::clientThreadFun, this, (LPVOID)c);
sth.detach();
}
}
}
DWORD WINAPI HttpServer::clientThreadFun(LPVOID lpThreadParameter) {
SOCKET c = (SOCKET)lpThreadParameter;
int ret = 0;
do {
char buf[1024 * 2] = { 0 };
ret = recv(c, buf, sizeof(buf)-1, 0);
if(ret <= 0) {
break;
}
buf[ret] = '\0';
cout << "客户端" << c << "请求信息 : " << buf << endl;
if(!getRequest(buf)) {
break;
}
string connect = "124443656556677778cxgyushining";
string respStr = getResponse(connect);
ret = send(c, respStr.c_str(), respStr.size(), 0);
cout << "客户端" << c << "请求应答信息 : " << respStr << endl;
break;
} while(ret != SOCKET_ERROR && ret != 0);
closesocket(c);
return 0;
}
bool HttpServer::init() {
_listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_HOPOPTS);
if(INVALID_SOCKET == _listenSocket) {
cout << "socket error :" << WSAGetLastError() << endl;
return false;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(_port);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
int len = sizeof(sockaddr_in);
if(SOCKET_ERROR == ::bind(_listenSocket, (sockaddr*)&addr, len)) {
cout << "bind error: " << WSAGetLastError() << endl;
return false;
}
if(SOCKET_ERROR == listen(_listenSocket, 1000)) {
cout << "listen error:" << WSAGetLastError() << endl;
return false;
}
cout << "create listen success :" << endl;
cout << "init htttpserver success :" << endl;
return true;
}
void HttpServer::stop() {
_isExit = true;
closesocket(_listenSocket);
}
bool HttpServer::getRequest(string requestStr) {
string src = requestStr;
string pattern = "^([A-Z]+) /([a-zA-Z0-9]*([.][a-zA-Z]*)?)[?]?(.*) HTTP/1";
regex r(pattern);
smatch mas;
regex_search(src, mas, r);
if(mas.size() == 0) {
cout << pattern.c_str() << " failed!" <<endl;
return false;
}
string type = mas[1];
string path = "/";
path += mas[2];
string filetype = mas[3];
string queryStr = mas[4];
if(type != "GET" && type != "POST") {
cout << "Not GET and POST!\n" << endl;
return false;
}
vector<string> querys;
splitStr(queryStr, querys, "&");
return true;
}
std::string HttpServer::getResponse(string connect) {
string rmsg = "";
rmsg = "HTTP/1.1 200 OK\r\n";
rmsg += "Server: xHttp\r\n";
rmsg += "Content-Type: text/html;charset=utf-8\r\n";
rmsg += "Content-Length: ";
rmsg += to_string(connect.size());
rmsg += "\r\n";
rmsg += "\r\n\r\n";
rmsg += connect;
return rmsg;
}
main.cpp
#include "HttpServer.hpp"
int main(int argc, char* argv[]) {
unsigned short port = 8892;
HttpServer server;
server.start(port);
getchar();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)