Http服务器-第二步支持单纯的文件请求

梦想游戏人
目录:
C/C++

实现完整的网页浏览支持

#include <iostream>
#include <list>
#include <string>
#include <algorithm>
#include <vector>
#include <thread>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
/*
#include <functional>
#include "direct.h"
#include <map>
#include <memory>
#include <queue>
#include <condition_variable>
#include <mutex>
#include <atomic>

#include <unordered_map>
*/

#include "winsock.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#pragma comment (lib,"wsock32")


using namespace  std;



typedef struct
{
	int size;
	unsigned char *buffer;
}FileData;



typedef struct
{
	int client;
	int size;
	unsigned char *buffer;
}SendBuffer;



class FileReader
{
public:
	~FileReader()
	{
		if (this->data.buffer)
			delete this->data.buffer;
	}
	FileReader(string &fileName)
	{
		this->name = fileName;
		memset((void*)&this->data, 0, sizeof(FileData));

	}

	bool ReadFile()
	{

		FILE *file = fopen(this->name.c_str(), "rb");
		if (!file)
		{
			cout << " error open file : " << name << endl;

			return false;
		}
		cout << name << endl;
		fseek(file, 0, SEEK_END);
		int size = ftell(file);
		fseek(file, 0, SEEK_SET);

		unsigned char *buf = new  unsigned char[size];


		fread(buf, size, 1, file);

		this->data.size = size;
		this->data.buffer = buf;

		fclose(file);

		return true;
	}

	string name;
	string rb;
	FILE* file;
	FileData data;
};



void SendThread(void*arg1, void*arg2)
{
	SendBuffer *buf = (SendBuffer*)arg1;

	SendBuffer *buf1 = (SendBuffer*)arg2;


	send(buf->client, (const char*)buf->buffer, buf->size, 0);
	send(buf1->client, (const char*)buf1->buffer, buf1->size, 0);


	closesocket(buf->client);
	delete buf1->buffer;
	delete buf1;
	delete buf;

}




int main()
{
	WSADATA wsadata;
	WORD wVersion = MAKEWORD(2, 0);
	WSAStartup(wVersion, &wsadata);



	int sock, length;
	length = sizeof(sockaddr);


	struct sockaddr_in server_ipaddr, client_ipaddr;
	memset(&server_ipaddr, 0, length);
	server_ipaddr.sin_family = AF_INET;
	server_ipaddr.sin_port = htons(80);
	server_ipaddr.sin_addr.s_addr = inet_addr("127.0.0.1");


	char buff[4096]; int nbuff;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	::bind(sock, (sockaddr *)&server_ipaddr, length);


	listen(sock, 180);



	char *head =
		"HTTP/1.0 200 OK\n"
		"Content-Type: text/html\n\n";

	char *head_js =
		"HTTP/1.0 200 OK\n"
		"Content-Type: application/x-javascript\n\n";




	char *head_css =
		"HTTP/1.0 200 OK\n"
		"Content-Type: 	text/css\n\n";


	char *head_png =
		"HTTP/1.0 200 OK\n"
		"Content-Type: 	image/png\n\n";



	char *head_jpg =
		"HTTP/1.0 200 OK\n"
		"Content-Type: 	image/jpeg\n\n";


	char *head_exe =
		"HTTP/1.0 200 OK\n"
		"Content-Type: 	application/x-msdownload\n\n";





	char *html1 =
		"<html><head><title>我的第一个 HTML 页面</title></head><body>";

	char * p = "<p>body 元素的内容会显示在浏览器中。</p>";

	char *html2 = "<p>title 元素的内容会显示在浏览器的标题栏中。</p>"
		"</body></html>";


	std::cout << "start server ok" << std::endl;
	int sock_client, len;
	while (1)
	{

		sock_client = accept(sock, (sockaddr *)&client_ipaddr, &length);
		if (sock_client == SOCKET_ERROR)
		{

			WSACleanup();
			goto RETURN;

		}
		len = recv(sock_client, buff, 4095, 0);
		buff[len] = '\0';
		std::string s = buff;
		if (!s.size())
		{
			continue;
		}

		s = s.substr(0, s.find("\n"));

		int i = s.find(" ", 0);


		std::string type = s.substr(0, i++);
		std::string req = s.substr(i, s.find(" ", i) - i);
		cout << req << endl;

		req = req.substr(1, -1);
		req = req.substr(0, req.find('?'));

		fstream file;
		file.open(req, ios::in);


		s = req;

		char *h = head;


		if (s.find(".css") != string::npos)
		{
			h = head_css;
		}
		if (s.find(".js") != string::npos)
		{
			h = head_js;
		}if (s.find(".html") != string::npos)
		{
			h = head;
		}
		if (s.find(".png") != string::npos)
		{
			h = head_png;
		}

		if (s.find(".jpg") != string::npos)
		{
			h = head_jpg;
		}
		if (s.find(".exe") != string::npos)
		{
			h = head_exe;
		}




		FileReader* reader = new FileReader(req);
		reader->ReadFile();



		SendBuffer *sb = new SendBuffer;
		sb->size = strlen(h);
		sb->buffer = (unsigned char*)h;
		sb->client = sock_client;
		SendBuffer *sb2 = new SendBuffer;
		sb2->size = reader->data.size;
		sb2->buffer = (unsigned char*)reader->data.buffer;
		sb2->client = sock_client;



		std::thread t(SendThread, sb, sb2);
		t.detach();

		cout << endl;

	}

RETURN:

	system("pause");

	return 0;
}

运行结果

Scroll Up