GreensnoWorld
记录点滴,分享乐趣,一块凝固的时间
1012.网络编程-搭建简易HTTP服务器
C/C++  2023年4月23日

1. Server 端

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <signal.h>
#include "logger.h"

#define DEFAULT_PORT 16555
#define MAXLINK 1024

int sockfd, connfd;

void stopServerRunning(int p)
{
	close(sockfd);
	printf("Close Server.");
	exit(0);
}

void setResponse(char *buff)
{
	memset(buff, 0, sizeof(buff));
	strcat(buff, "HTTP/1.1 200 OK\r\n");
	strcat(buff, "Connection: close\r\n");
	strcat(buff, "\r\n");
	strcat(buff, "Hello\n");
}

int main()
{
	struct sockaddr_in servaddr;
	char buff[BUFSIZ];
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("Socket Error");
		return -1;
	}

	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(DEFAULT_PORT);
	if(bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
	{
		perror("Bind Error");
		return -1;
	}

	if(listen(sockfd, MAXLINK) == -1)
	{
		perror("Listen Error");
		return -1;
	}

	printf("Listening...\n");
	while(true)
	{
		signal(SIGINT, stopServerRunning);
		connfd = accept(sockfd, NULL, NULL);
		if(connfd == -1)
		{
			perror("Accept Error");
			return -1;
		}

		memset(buff, 0, sizeof(buff));
		recv(connfd, buff, BUFSIZ-1, 0);
		//printf("Receive: %s\n", buff);
		
		logger.Log("Receive: ", 9);
		logger.Log(buff, strlen(buff));
		setResponse(buff);
		send(connfd, buff, strlen(buff), 0);
		close(connfd);
	}
	return 0;
}

2. Client 端

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 16555

int main()
{
	struct sockaddr_in servaddr;
	char buff[BUFSIZ];
	int sockfd;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("Socket Error");
		return -1;
	}

	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr);
	servaddr.sin_port = htons(SERVER_PORT);
	if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)))
	{
		perror("Connect Error");
		return -1;
	}

	printf("Please input: ");
	scanf("%s", buff);
	send(sockfd, buff, strlen(buff), 0);
	memset(buff, 0, sizeof(buff));
	recv(sockfd, buff, BUFSIZ-1, 0);
	printf("Receive: %s\n", buff);
	close(sockfd);
	return 0;
}

3. Logger 类

#include <cstdlib>

class Logger
{
	char buff[BUFSIZ];
	int buffLen;
	FILE *fp;

public:
	Logger()
	{
		memset(buff, 0, sizeof(buff));
		buffLen = 0;
		fp = fopen("server.log", "a");
	}
	void Flush()
	{
		fputs(buff, fp);
		memset(buff, 0, sizeof(buff));
		buffLen = 0;
	}
	void Log(const char *str, int len)
	{
		if(buffLen + len > BUFSIZ-10)
		{
			Flush();
		}
		for(int i=0; i<len; i++)
		{
			buff[buffLen] = str[i];
			buffLen++;
		}
	}
	~Logger()
	{
		if(buffLen != 0)
		{
			Flush();
		}
		fclose(fp);
	}

}logger;

4. HTTP 请求

curl -v http://127.0.0.1:16555/

5. 压力测试

ab -c 100 -n 10000 -r http://127.0.0.1:16555/
LIJG
余本顽劣,生于紫云下,长于汝水滨。早年求学,兴趣广泛,好高骛远,学无所成,仓皇入世。兴趣所致,投身互联网,求知未证,而立已至,始悟光阴荏苒,终需务实钻研。故有此站,记录时光,积累点滴,验证所学,分享愚见。指舞方寸间,心系万千年。
留言