Simple implementation of web server in c++ (can be used directly)

Service-Terminal

#include <iostream>
#include<winsock.h>
#include <thread>
#include <string>


#pragma comment(lib,"ws2_32.lib")




// 处理HTTP请求
std::string handleRequest(const std::string& method, const std::string& uri, const std::string& body) {
	std::string response;
	if (method == "GET") {

	
		// 处理GET请求
		response = "HTTP/1.1 200 OK\r\n"
			"Content-Type: text/html; charset=utf-8\r\n"
			"\r\n"
			"<html><head><title>Get Request</title></head><body><h1>Get Request Received!</h1></body></html>\r\n\r\n";
	}
	else if (method == "POST") {
		// 处理POST请求
		response = "HTTP/1.1 200 OK\r\n"
			"Content-Type: text/html; charset=utf-8\r\n"
			"\r\n"
			"<html><head><title>Post Request</title></head><body><h1>Post Request Received!</h1><p>" + body + "</p></body></html>\r\n\r\n";
	}
	else {
		
		// 处理其他请求
		response = "HTTP/1.1 404 Not Found\r\n"
			"Content-Type: text/html; charset=utf-8\r\n"
			"\r\n"
			"<html><head><title>Not Found</title></head><body><h1>404 Not Found</h1></body></html>\r\n\r\n";
	}

	return response;
}

// 处理客户端连接
void handleClient(int client_socket) {
	char buffer[1024];

	while (true) {
		std::cout << "等待客户端数据中...." << std::endl;

		// 接收HTTP请求
		std::string request;
		int n = recv(client_socket, buffer, 1024, 0);
		if (n <= 0) {
			break;
		}

		std::cout << "已收到数据,客户端的数据是:\n" << buffer << std::endl;

		//客户端发送过来的信息
		std::string mes = buffer;
		//判断信息中是否正常的http请求,如果不是,则直接返回非法请求
		if (mes.find("HTTP") == -1) {
			std::string result = "聊天模式,不关闭socket";
			send(client_socket, result.c_str(), result.length(), 0);
			continue;
		}

		request.append(buffer, n);

		// 解析HTTP请求
		size_t pos = request.find(' ');
		if (pos == std::string::npos) {
			continue;
		}
		std::string method = request.substr(0, pos);

		pos = request.find(' ', pos + 1);
		if (pos == std::string::npos) {
			continue;
		}
		std::string uri = request.substr(request.find(' ') + 1, pos - request.find(' ') - 1);

		// 查找HTTP请求头结束位置
		pos = request.find("\r\n\r\n");
		if (pos == std::string::npos) {
			continue;
		}

		// 解析HTTP请求Body
		std::string body = request.substr(pos + 4);

		// 处理HTTP请求
		std::string response = handleRequest(method, uri, body);

		// 发送HTTP响应
		send(client_socket, response.c_str(), response.length(), 0);


		std::cout << "给客户端返回数据:" << response<<std::endl;
		std::cout << "给客户端返回数据完毕" << std::endl;

		// 关闭连接
		// 5.断开连接 end
		closesocket(client_socket);  //这个关闭后,客户端连接就断开了(如果不断开就可以持续和客户端交互)
		//WSACleanup();
		

		//跳出循环
		break;
	}
}

int main()
{
	std::cout << "Hello World!\n";
	WSADATA wsdata;
	std::cout << "start up now ...." << std::endl;
	if (WSAStartup(MAKEWORD(2, 2), &wsdata))
	{
		std::cout << "init socket failed!" << std::endl;
		WSACleanup();
		return FALSE;
	}
	std::cout << "before create socket ...." << std::endl;
	SOCKET s_server, s_accept;
	s_server = socket(PF_INET, SOCK_STREAM, 0);
	if (s_server == INVALID_SOCKET)
	{
		std::cout << "create socket fail" << std::endl;
		WSACleanup();
		return FALSE;
	}
	std::cout << "create socket success...." << std::endl;
	//填充服务端信息
	SOCKADDR_IN server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(8226);
	//当然这里也可以将 127.0.0.1改成你想要的ip或者 INADDR_ANY 为向所有ip发送信息
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	//数据绑定服务器 s_server为服务端套接字
	std::cout << "before bind socket ...." << std::endl;
	if (bind(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
	{
		std::cout << "Binding Socket fail.......!" << std::endl;
		WSACleanup();
		return FALSE;
	}
	std::cout << "bind socket success...." << std::endl;

	std::cout << "before listen socket ...." << std::endl;
	if (listen(s_server, 1) == SOCKET_ERROR)
	{
		std::cout << "Listening Socket fail........!" << std::endl;
		WSACleanup();
		return FALSE;
	}
	std::cout << "listen socket success...." << std::endl;


	sockaddr_in accept_addr;         //用来记录请求连接的套接字信息
	int len = sizeof(SOCKADDR);
	char recv_buf[8192] = { 0 };
	char send_buf[1024] = { 0 };
	while (true)
	{
		//接受连接请求
		std::cout << "wait accept...." << std::endl;
		//这里会阻塞等待客户端连接
		s_accept = accept(s_server, (SOCKADDR*)&accept_addr, &len);
		if (s_accept == SOCKET_ERROR) {
			std::cout << "Error: accept failed !" << std::endl;

			//连接失败,释放socket
			WSACleanup();
			break;
		}
		std::cout << "建立连接成功...." << std::endl;

	
		
	
		//处理客户端连接
		handleClient(s_accept);

		//启动线程去处理请求
		//std::thread client_thread(handleClient, s_accept);
		//client_thread.detach();
		
			

	

	}

	

}

client:

#include <iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
#include <string.h>


using namespace std;


int main()
{
	std::cout << "Hello World!\n";
	WSADATA wsdata;
	if (WSAStartup(MAKEWORD(2, 2), &wsdata))
	{
		std::cout << "init socket failed!" << std::endl;
		WSACleanup();
		return FALSE;
	}
	//检测版本号
	if (LOBYTE(wsdata.wVersion) != 2 || HIBYTE(wsdata.wHighVersion) != 2) {
		std::cout << "Error: wsadata.wVersion != 2 ." << std::endl;
		WSACleanup();
		return -1;
	}

	SOCKET client;
	client = socket(PF_INET, SOCK_STREAM, 0);
	if (client == INVALID_SOCKET)
	{
		std::cout << "create socket fail" << std::endl;
		WSACleanup();
		return FALSE;
	}
	//填充服务端信息
	SOCKADDR_IN server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	server_addr.sin_port = htons(8226);


	//发送连接请求 请求连接服务器
	if (connect(client, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		std::cout << "Error: connect server failed !" << std::endl;
		WSACleanup();
		return -1;
	}
	std::cout << "成功连接到服务器" << std::endl;
	


	//发送消息(自己重组的一个循环)
	while (true)
	{
	
		string str="";
		int choose = 0;
		cout << "***************************" << endl;
		cout << "*****  1、发送Get请求(接收响应信息后,断开socket连接)*****" << endl;
		cout << "*****  2、发送Post请求(接收响应信息后,断开socket连接) *****" << endl;
		cout << "*****  3、非法请求(聊天模式,不断开socket连接)*****" << endl;
		cout << "*****  0、退出客户端  *****" << endl;
		/*cout << "*****  5、修改联系人  *****" << endl;
		cout << "*****  6、清空联系人  *****" << endl;
		cout << "*****  0、退出通讯录  *****" << endl;*/
		cout << "***************************" << endl;
		std::cout << "请输入你的选择:" << std::ends;
		std::cin >> choose;

		if (choose==0) {
			//退出客户端
			break;
		}
		
		string rows = "";
		string header = "";

		switch (choose)
		{
		case 1:
			//get请求
			rows = "GET /check?a=1,2,3 HTTP/1.1\r\n";
			header = "Connection:Keep-Alive\r\n"
				"Accept-Encoding:gzip, deflate\r\n"
				"Accept-Language:zh-CN,en,*\r\n"
				"Content-Length:114\r\n"
				"User-Agent:Mozilla/5.0\r\n\r\n";
			break;
		case 2:
			//post请求
			rows = "POST /check HTTP/1.1\r\n";
			header = "Connection:Keep-Alive\r\n"
					"Accept-Encoding:gzip, deflate\r\n"
					"Accept-Language:zh-CN,en,*\r\n"
					"Content-Length:114\r\n"
					"Content-Type:application/x-www-form-urlencoded; charset=UTF-8\r\n"
					"host:tmalarm.vemic.com\r\n"
					"User-Agent:Mozilla/5.0\r\n"
				    "请求数据\r\n\r\n";
			break;
		case 3:
			cout << "请输入你要发送得消息:"<< ends;
			cin >> str;
			break;
		default:
			break;
		}
		
		
		str += "\r\n\r\n";
		//	封装get/post请求
		string path = rows + header+str;
		char* bufsend = const_cast<char*>(path.c_str());


		char temp[1024] = { 0 };
		std::cout << "开始发送数据....." << std::endl;
		snprintf(temp, sizeof(temp), "%s", bufsend);
		//发送消息
		int sendLen = send(client, (char*)temp, sizeof(temp), 0);

		if (sendLen < 0) {
			std::cout << "Error: send info to server failed !" << std::endl;
			return -1;
		}
		std::cout << "发送数据成功、等待服务器响应....." << std::endl;

		char recv_buf[8192] = { 0 };
		int recv_len = recv(client, recv_buf, sizeof(recv_buf), 0);  //接收服务端信息,若接收不到,会阻塞在这里
		if (recv_len < 0) {
			std::cout << "Error: receive info from server failed !" << std::endl;
			return -1;
		}
		std::cout << "收到了服务器返回的信息 内容是:" << recv_buf << std::endl;
	}
	




	

	发送数据
	//char temp[1024] = { 0 };
	//std::cout << "开始发送数据....." << std::endl;
	//snprintf(temp, sizeof(temp), "%s", "我是客户端 我发送信息给你了服务端");
	//int sendLen = send(client, (char*)temp, sizeof(temp), 0);
	//if (sendLen < 0) {
	//	std::cout << "Error: send info to server failed !" << std::endl;
	//	return -1;
	//}

	/*std::cout << "发送数据成功、等待服务器响应....." << std::endl;
	char recv_buf[8192] = { 0 };
	int recv_len = recv(client, recv_buf, sizeof(recv_buf), 0);
	if (recv_len < 0) {
		std::cout << "Error: receive info from server failed !" << std::endl;
		return -1;
	}
	std::cout << "收到了服务器返回的信息 内容是:" << recv_buf << std::endl;*/

	system("pause");
}

Guess you like

Origin blog.csdn.net/weixin_45533131/article/details/130468413