0
点赞
收藏
分享

微信扫一扫

内网安全-内网穿透

金刚豆 2024-02-15 阅读 26

第一步:新建项目

1、打开VS点击创建新项目

2、选择空项目并点下一步(切记不能选错项目类型)

3、填写项目名称和路径,点击创建即可

 

新建好后项目是这样的比较干净 

4、右击源文件,点击添加,新建http.cpp文件

第二步:前期准备

在http.cpp最上面引入依赖,并撰写main方法,打印错误日志的方法

#include<stdio.h>
#include<string.h>
#include<WinSock2.h>
#include<sys/types.h>
#include<sys/stat.h>
#pragma comment(lib,"WS2_32.lib")
#define PRINTF(str) printf("[%s - %d]"#str"%s",__func__,__LINE__,str);

//打印错误日志
void error_die(const char* str) {
perror(str);
exit(1);

}



int main(void) {


return 0;
}

第三步:网络初始化

初始化可以分为五步:1、网络通讯初始化===>>>2、创建套接字===>>>3、绑定端口===>>>4、绑定套接字===>>>5、创建监听队列

代码实现如下:

int startup(unsigned short *port) {

//1、网络通讯初始化
WSADATA data;
int res = WSAStartup(MAKEWORD(1,1),
if (res) {
error_die("init fail");
}
//2、创建套接字
int server_socket = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);

if (server_socket == -1) {
error_die("sock create fail");
}

//3、绑定端口
int opt = 1;
res = setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,(const char*) & opt, sizeof(opt));

if (res) {
error_die("port bing fail");
}

//4、绑定套接字
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(*port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

res = bind(server_socket,(struct sockaddr*) &server_addr, sizeof(server_addr));

if (res<0) {
error_die("sock bing fail");
}

//5、创建监听队列
int nameLen = sizeof(server_addr);
if (*port == 0) {
res = getsockname(server_socket, (struct sockaddr*)&server_addr,
if (res) {
error_die("dynamic sock create fail");
}

*port = server_addr.sin_port;
}


res = listen(server_socket, 5);
if (res < 0) {
error_die("listen queque create fail");
}
return server_socket;

};

main方法修改如下:

int main(void) {
//1、初始化
unsigned short port = 8000;
int server_sock = startup(
printf("http have benn started ,listening [%d] port...",port);

return 0;
}

第四步:处理用户请求

1、报文背景知识

浏览器发起新的访问时,会向服务器端发送一个请求报文。例如,在浏览器地址输入 127.0.0.1:8000 回车后,服务器端收到的完整报文如下:

请求报文由4四个部分组成:请求行、请求头部行、空行、请求数据。具体格式如下:

2、具体处理

具体处理代码如下:

//从指定的客户端套接字读取一行数据,保持到buff中,返回实际读取到了字节数
int get_line(int sock, char* buff, int size) {
char c = 0;
int i = 0;
while (i < size - 1 '\n') {
int n = recv(sock,
if (n > 0) {
if (c == '\r') {
n = recv(sock, &c, 1, MSG_PEEK);
if (n > 0 = '\n') {
recv(sock,
}
else {

c = '\n';
}
}
buff[i++] = c;
}
else {

c = '\n';
}
}
buff[i] = 0;
return 0;
}

//向指定套接字,发送一个未支持提示还没有实现的错误页面
void unimplement(int client) {

char buf[1024];

sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n");
send(client, buf, strlen(buf), 0);

sprintf(buf, SERVER_STRING);
send(client, buf, strlen(buf), 0);
sprintf(buf, "Content-Type: text/html\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "</TITLE></HEAD>\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "<BODY><P>HTTP request method not supported.\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "</BODY></HTML>\r\n");
send(client, buf, strlen(buf), 0);

}

//向指定套接字,发送一个未支持提示还没有实现的错误页面
void not_found(int client) {

char buf[1024];

sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, SERVER_STRING);
send(client, buf, strlen(buf), 0);
sprintf(buf, "Content-Type: text/html\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "<HTML><TITLE>Not Found</TITLE>\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "<BODY><P>The server could not fulfill\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "your request because the resource specified\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "is unavailable or nonexistent.\r\n");
send(client, buf, strlen(buf), 0);
sprintf(buf, "</BODY></HTML>\r\n");
send(client, buf, strlen(buf), 0);

}




//发送响应的头信息
void headers(int client) {

char buff[1024];
strcpy(buff, "HTTP/1.0 200 OK\r\n");
send(client, buff, strlen(buff), 0);


strcpy(buff, "Server:MyHttpd/0.1\r\n");
send(client, buff, strlen(buff), 0);

strcpy(buff, "Content-type:text/html\n");
send(client, buff, strlen(buff), 0);


strcpy(buff, "\r\n");
send(client, buff, strlen(buff), 0);

}


//发送文件
void cat(int client,FILE* resource) {
char buff[4096];
int count = 0;
while (1) {
int ret = fread(buff, sizeof(char), sizeof(buff), resource);
if (ret <= 0) {
break;
}
send(client, buff, ret, 0);
count += ret;
}
printf("total send [%d] to client\n",count);
}




void server_file(int client,const char* fileName) {
char numchars = 1;
char buff[1024];
while (numchars > 0 && strcmp(buff, "/n")) {
numchars = get_line(client, buff, sizeof(buff));
PRINTF(buff);
}

FILE* resource = fopen(fileName,"r");

if (resource==NULL) {
not_found(client);
}
else {
//发送头信息
headers(client);
//发送文件
cat(client, resource);

printf("file send success");

}
fclose(resource);

}



DWORD WINAPI accept_request(LPVOID arg) {
char buff[1024];
int client = (SOCKET)arg;
//1、获取第一行
int numchars = get_line(client, buff,sizeof(buff));
PRINTF(buff);

char method[255];
int j = 0 ,i =0;
while (!isspace(buff[j])&&i < sizeof(method)-1) {
method[i++] = buff[j++];
}
method[i] = 0;
PRINTF(method);


//2、检查请求方法是否支持
if (stricmp(method,"GET")&& stricmp(method, "POST")) {
//向浏览器返回错误提示页面
unimplement(client);
return 0;
}


//3、解析资源路径
char url[255];
i = 0;
while (isspace(buff[j]) && j < sizeof(buff)) {
j++;
}
while (!isspace(buff[j])&& sizeof(url)-1 && j < sizeof(buff)) {
url[i++] = buff[j++];
}
url[i] = 0;
PRINTF(url);

char path[512] = "";
sprintf(path, "htdocs%s", url);
if (path[strlen(path)-1]=='/') {
strcat(path, "index.html");

}
PRINTF(path);

struct stat status ;
if (stat(path,&status)==-1) {
//把请求包里的东西读完
while (numchars>0&&strcmp(buff,"/n")) {
numchars = get_line(client, buff, sizeof(buff));
}
PRINTF(buff);
not_found(client);
}else {
if ((status.st_mode & S_IFMT)==S_IFDIR) {
strcat(path, "index.html");
}
server_file(client,path);
}

closesocket(client);

return 0;
}

github地址:

https://github.com/1756336885/miniWeb.git

gitee地址:

miniWeb: 迷你版的web,用C++撰写,后期会添加数据库,中间件相关的操作

参考文章:

2-创建项目_哔哩哔哩_bilibili

C语言手写HTTPD网站服务器_126775241csdn-CSDN博客

举报

相关推荐

0 条评论