#include<stdio.h>
#include<string>
#include<iostream>
#include<map>
#include <ctime>
#include<WinSock2.h> // 包含网络编程头文件,进入静态库
#pragma comment(lib,"ws2_32.lib")
#include<process.h>//多线程相关
using namespace std;
//最大传输大小
#define MAXSIZE 1024
unsigned WINAPI RequestHandler(void* arg);
int merror(int redata, int error, const char* showinfo) {
if (redata == error) {
perror(showinfo);
getchar();
return -1;
}
}
void sendhtml(SOCKET s, char *filename);
//按行读取接收报文
string ReadLine(char recieve[], int &loc)
{
int next_char;
string data = "";
while (true)
{
next_char = recieve[loc++];
if (next_char == '\n')
{
break;
}
else if (next_char == '\r')
{
continue;
}
else if (next_char == '\0')
{
break;
}
data += next_char;
}
return data;
}
int main() {
DWORD dwThreadTD;
printf("welcome to my web server!\n");
WSADATA wsdata;
int is_ok = WSAStartup(MAKEWORD(2,2), &wsdata); // 确定socke版本信息
merror(is_ok, WSAEINVAL,"申请socket失败!");
SOCKET server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // af_inet使用ipv4地址
merror(server,INVALID_SOCKET, "创建socket失败");
SOCKADDR_IN seraddr;
seraddr.sin_family = AF_INET; // 和创建时一样 ipv4
seraddr.sin_port = htons(80); //网络是大端存储, pc是小端存储,需要转换
seraddr.sin_addr.s_addr = INADDR_ANY;// 监听任意地址
is_ok = bind(server,(SOCKADDR *)&seraddr,sizeof(seraddr));
merror(is_ok, SOCKET_ERROR, "socket绑定失败!");
is_ok = listen(server, 5); // 客户端连接数量
merror(is_ok, SOCKET_ERROR, "监听失败!");
SOCKADDR_IN claddr; // 客户端信息
int cllen = sizeof(claddr);
/*
开启服务器监听
*/
while (1) {
SOCKET client = accept(server,(SOCKADDR *) &claddr,&cllen); //建立TCP连接
HANDLE hTread = (HANDLE)_beginthreadex(NULL, 0, RequestHandler, (void*)client, 0, (unsigned*)&dwThreadTD);//建立多线程
merror(client, INVALID_SOCKET, "连接失败!");
}
closesocket(server);
WSACleanup();
getchar();
return 0;
}
void HandleHTTPRequest(char revdata[])
{
//请求分为GET请求和POST请求
}
//处理HTTP请求类
class HttpRequestHandle {
public:
//初始化
HttpRequestHandle(char recieved[]) {
memcpy(recieve, recieved, MAXSIZE);
loc = 0;
Http_method = "";
Http_url = "";
}
//获得请求头
void GetHeadInfo() {
string line;
string head = ReadLine(recieve, loc);//请求行
//获得方法
int loc_head = 0;
while (head[loc_head] != ' ') {
Http_method += head[loc_head];
loc_head++;
}
loc_head++;
while (head[loc_head] != ' ') {
Http_url += head[loc_head];
loc_head++;
}
while ((line = ReadLine(recieve, loc)) != "") {
//分解报文头
int seq_index = line.find_first_of(":");
if (seq_index != -1) {
string type = line.substr(0,seq_index);
string value = line.substr(seq_index+1,line.size());
HttpHeaders.insert({ type,value });
}
cout << line << endl;
}
}
void GetHttpBody() {
while (recieve[loc] != '\0') {
body += recieve[loc];
loc++;
}
}
string GetMethod() {
return Http_method;
}
string GetURL() {
return Http_url;
}
string GetBody() {
return body;
}
private:
char recieve[MAXSIZE];//接收字符
string Http_method;//请求方式
string Http_url;//URL地址
string body;
map<string, string> HttpHeaders;
int loc;//读取位置
};
//处理方法类
class MyFunction {
public:
MyFunction(string Http_method, string Http_url, string body) {
this->body = body;
this->Http_method = Http_method;
this->Http_url = Http_url;
}
string Deal() {
string deal_str = "";
if (Http_method == "GET") {
int id = choose();
switch (id) {
case 1:
deal_str = test();
break;
default:
break;
}
}
else if (Http_method == "POST") {
}
return deal_str;
}
//根据URL选择方法
int choose() {
if (Http_url == "") {
}
else {
return 1;
}
}
//方法1:测试用
string test() {
return "hello";
}
private:
string Http_method;//请求方式
string Http_url;//URL地址
string body;
};
class HttpResponseHandle {
public:
HttpResponseHandle(string send) {
this->send = send;
Http_State = "200";//成功状态
Http_phrase = "OK";
Http_protocol_versionstring = "HTTP/1.1";
char right_time[50];
struct tm t; //tm结构指针
time_t now;
time(&now);
localtime_s(&t, &now);
//HttpHeaders.insert({ "Date",t.tm_year+1900+"" });
HttpHeaders.insert({ "Content-Type","application/json; charset=UTF-8" });
HttpHeaders.insert({ "Content-Length","0" });
}
void SetSend() {
string headerstr = "";
headerstr = Http_protocol_versionstring + " " + Http_State + " " + Http_phrase + "\r\n";
string Header_line = "";
map<string, string>::reverse_iterator iter;
HttpHeaders["Content-Length"] = ""+send.size();
for (iter = HttpHeaders.rbegin(); iter != HttpHeaders.rend(); iter++) {
Header_line += iter->first + ":" + iter->second + "\r\n";
}
headerstr += Header_line ;
send = headerstr + "\r\n" + send;
}
string GetSend() {
return send;
}
private:
string Http_State;
string Http_phrase;
string Http_protocol_versionstring;
map<string, string> HttpHeaders;
string send;
};
unsigned WINAPI RequestHandler(void* arg)
{
SOCKET client = (SOCKET)arg;
char revdata[MAXSIZE] = "";
int loc = 0;
recv(client, revdata, MAXSIZE, 0);//接收报文
HttpRequestHandle httpreq(revdata);
httpreq.GetHeadInfo();
httpreq.GetHttpBody();
MyFunction function(httpreq.GetMethod(), httpreq.GetURL(), httpreq.GetBody());
string response_str = function.Deal();
HttpResponseHandle response(response_str);
response.SetSend();
string send_str = response.GetSend();
//cout << "接收到的数据:" << revdata << endl;
//cout << "共接收数据大小" << strlen(revdata) << endl;
//char senddata[1024] = "<h1 style=\"color:blue;font-size:80px\">hello this is server end</h1>";
//send(client, senddata, strlen(senddata), 0);
cout << send_str << endl;
send(client, send_str.c_str(), strlen(send_str.c_str()), 0);
//char *filename = (char*)"index.html";
//char *fileName = (char*)"index.html";
//sendhtml(client, fileName);
closesocket(client);
return 0;
}
void sendhtml(SOCKET s, char *filename) {
char protocol[] = "HTTP/1.0 200 OK\r\n";
char serName[] = "server:simple web server\r\n";
char cntLen[] = "Conten-length:2048\r\n";
char cntType[100];
sprintf_s(cntType, "Content-type:%s\r\n\r\n", "text/html");
cout << cntType << endl;
send(s, protocol, strlen(protocol), 0);
send(s, serName, strlen(serName), 0);
send(s, cntLen, strlen(cntLen), 0);
send(s, cntType, strlen(cntType), 0);
//打开文件
FILE* pfile;
errno_t err = fopen_s(&pfile, filename, "r");
if (pfile == NULL) {
cout << "can not open the file!" << endl;
return;
}
char temp[1024] = "";
do {
fgets(temp, 1024, pfile);
send(s, temp, strlen(temp), 0);
} while (!feof(pfile));
}
C++服务器
最新推荐文章于 2025-04-16 18:30:43 发布