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/