2 Star 5 Fork 4

林慢慢/HttpServer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
TcpServer.hpp 3.18 KB
一键复制 编辑 原始数据 按行查看 历史
林慢慢 提交于 2023-03-10 20:49 . DEBUG
#pragma once
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "Log.hpp"
#define BACKLOG 5
class TcpServer{
private:
int _port; // 端口号
int _listen_sock; // 监听套接字
static TcpServer* _svr; // 指向单例对象的static指针
private:
TcpServer(int port)
:_port(port)
,_listen_sock(-1)
{}
TcpServer(const TcpServer&) = delete;
TcpServer* operator=(const TcpServer&) = delete;
public:
static TcpServer* GetInstance(int port)// 单例
{
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
if (_svr == nullptr)
{
pthread_mutex_lock(&mtx);
if (_svr == nullptr)// 为什么要两个if? 原因:当首个拿锁者完成了对象创建,之后的线程都不会通过第一个if了,而这期间阻塞的线程开始唤醒,它们则需要靠第二个if语句来避免再次创建对象。
{
_svr = new TcpServer(port);
_svr -> InitServer();
}
pthread_mutex_unlock(&mtx);
}
return _svr;
}
void InitServer()
{
Socket(); // 创建
Bind(); // 绑定
Listen(); // 监听
LOG(INFO, "TcpServer Init Success");
}
void Socket() // 创建监听套接字
{
_listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (_listen_sock < 0)
{
LOG(FATAL, "socket error!");
exit(1);
}
int opt = 1;// 将 SO_REUSEADDR 设置为 1 将允许在端口上快速重启套接字
setsockopt(_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
LOG(INFO, "creat listen_sock success");
}
void Bind() // 绑定端口
{
struct sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(_port);
local.sin_addr.s_addr = INADDR_ANY;
if (bind(_listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0)
{
LOG(FATAL, "bind error");
exit(2);
}
LOG(INFO, "port bind listen_sock success");
}
void Listen() // 监听
{
if (listen(_listen_sock, BACKLOG) < 0) // 声明_listen_sock处于监听状态,并且最多允许有backlog个客户端处于连接等待状态,如果接收到更多的连接请求就忽略
{
LOG(FATAL, "listen error");
exit(3);
}
LOG(INFO, "listen listen_sock success");
}
int Sock() // 获取监听套接字fd
{
return _listen_sock;
}
~TcpServer()
{
if (_listen_sock >= 0)
{
close(_listen_sock);
}
}
};
// 单例对象指针初始化
TcpServer* TcpServer::_svr = nullptr;
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/linkylo/HttpServer.git
git@gitee.com:linkylo/HttpServer.git
linkylo
HttpServer
HttpServer
master

搜索帮助