리눅스랑 코드 동기화

This commit is contained in:
2025-05-01 16:33:52 +09:00
parent d3161edb36
commit 4fb5bdd4cb
14 changed files with 279 additions and 144 deletions

View File

@@ -13,16 +13,10 @@
#include "precomp.hpp"
void _TCPClient(Chattr::TCPSocket sock, Chattr::Address addr);
void _TCPRecvClient(Chattr::ThreadPool* thread, Chattr::TCPSocket sock, Chattr::Address addr);
void _TCPSendClient(Chattr::ThreadPool* thread, Chattr::TCPSocket sock, Chattr::Address addr, std::queue<Chattr::ResponsePacket> packets);
int main() {
Chattr::Snowflake flake;
flake.instance = 513;
flake.sequence = 2049;
flake.timestamp = 2199023255553;
spdlog::info("{}", sizeof(Chattr::Snowflake));
std::cout << std::bitset<64>(flake.snowflake) << "(" << std::hex << flake.snowflake << ")" << std::endl;
return 0 ;
struct Chattr::WSAManager wsaManager;
auto config = Chattr::ConfigManager::load();
Chattr::log::setDefaultLogger(config.logLevel, config.logFileName, config.logfileSize, config.logfileCount);
@@ -41,7 +35,7 @@ int main() {
serveraddr.set(AF_INET6, in6addr_any, config.listenPort);
clientAddr.setType(AF_INET6);
}
sock.bind(&serveraddr.addr, serveraddr.length);
sock.bind(serveraddr);
sock.listen(SOMAXCONN);
#ifdef _WIN32
@@ -53,7 +47,7 @@ int main() {
Chattr::ThreadPool threadPool(0);
int returnedIntager = 0;
/*int returnedIntager = 0;
int passvalue = 2;
threadPool.enqueueJob([](int& i){
spdlog::info("JobTest");
@@ -62,27 +56,110 @@ int main() {
return 2;
}
return 1;
}, returnedIntager, std::ref(passvalue));
}, returnedIntager, std::ref(passvalue));*/
while (true) {
spdlog::info("Waiting for connection...");
sock.accept(clientSock, clientAddr);
threadPool.enqueueJob(_TCPClient, std::move(clientSock), clientAddr);
threadPool.enqueueJob(_TCPRecvClient, std::move(clientSock), clientAddr);
}
}
void _TCPClient(Chattr::TCPSocket sock, Chattr::Address addr) {
spdlog::info("Connection accepted. [{}]", (std::string)addr);
void _TCPRecvClient(Chattr::ThreadPool* thread, Chattr::TCPSocket sock, Chattr::Address addr) {
Chattr::Packet pack;
int packetSize = 1500;
int totalRedSize = 0;
int redSize = 0;
char buf[1024];
while (true) {
int redSize = sock.recv(buf, 1024, 0);
if (redSize == 0)
break;
std::string recvData(buf, redSize);
spdlog::info("Red size : {}, {}", redSize, recvData);
while (totalRedSize < packetSize) {
redSize = sock.recv(&pack.serialized, 1500 - totalRedSize, 0);
if (redSize <= 0) {
spdlog::info("Client disconnected. [{}]", (std::string)addr);
return;
}
totalRedSize += redSize;
}
spdlog::info("Client disconnected. [{}]", (std::string)addr);
std::string recvString;
bool packetError = false;
Chattr::DataPostPacket dataPostPacket;
switch (pack.__data.packetType) {
case Chattr::PacketType::PACKET_POST:
switch (pack.__data.dataType) {
case Chattr::DataType::TEXT:
std::memcpy(&dataPostPacket.serialized, &pack, 1500);
dataPostPacket.convToH();
recvString = std::string((char *)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - sizeof(std::uint16_t));
spdlog::info("Red size : {}, {} from : [{}]", redSize, recvString, (std::string)addr);
break;
case Chattr::DataType::BINARY:
break;
default:
packetError = true;
break;
}
break;
case Chattr::PacketType::PACKET_REQUEST:
switch (pack.__data.requestType) {
case Chattr::RequestType::LOGIN:
break;
case Chattr::RequestType::ROOM_CREATE:
break;
case Chattr::RequestType::ROOM_LIST:
break;
case Chattr::RequestType::ROOM_JOIN:
break;
case Chattr::RequestType::ROOM_EXIT:
break;
case Chattr::RequestType::USERS_LIST:
break;
default:
packetError = true;
break;
}
break;
case Chattr::PacketType::PACKET_CONTINUE:
break;
default:
packetError = true;
break;
}
if (packetError) {
Chattr::ResponsePacket packet;
packet.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST;
std::queue<Chattr::ResponsePacket> packs;
packet.convToN();
packs.push(packet);
thread->enqueueJob(_TCPSendClient, std::move(sock), addr, packs);
}
else
thread->enqueueJob(_TCPRecvClient, std::move(sock), addr);
}
void _TCPSendClient(Chattr::ThreadPool* thread, Chattr::TCPSocket sock, Chattr::Address addr, std::queue<Chattr::ResponsePacket> packets) {
Chattr::ResponsePacket pack = packets.front();
packets.pop();
int packetSize = 1500;
int totalSentSize = 0;
int sentSize = 0;
while (totalSentSize < packetSize) {
sentSize = sock.send(&pack.serialized, 1500 - totalSentSize, 0);
if (sentSize <= 0) {
spdlog::info("Client disconnected. [{}]", (std::string)addr);
return;
}
totalSentSize += sentSize;
}
if (packets.empty())
thread->enqueueJob(_TCPRecvClient, std::move(sock), addr);
else
thread->enqueueJob(_TCPSendClient, std::move(sock), addr, packets);
}

View File

@@ -1,28 +1,60 @@
#include "Session/Session.hpp"
namespace Chattr {
Session::Session(Chattr::TCPSocket __sock) {
init(std::move(__sock));
}
Session::~Session() {
destruct();
}
void Session::init(Chattr::TCPSocket __sock) {
}
void Session::destruct() {
}
int Session::send() {
return -1;
}
int Session::recv() {
return -1;
}
}
//#include "Session/Session.hpp"
//#include "Socket/Log.hpp"
//#include "precomp.hpp"
//#include <thread>
//
//namespace Chattr {
//
//Session::Session(Chattr::TCPSocket __sock) {
// init(std::move(__sock));
//}
//
//Session::~Session() {
// destruct();
//}
//
//void Session::init(Chattr::TCPSocket __sock) {
// sock_ = std::move(__sock);
//}
//
//void Session::destruct() {
//}
//
//TCPSocket Session::reconnect(Chattr::TCPSocket __sock, int maxTry) {
// int retVal = 0;
// int backoffTime = 2;
//
// __sock.destruct();
//
// spdlog::info("Lost connection.");
// while (maxTry--) {
// backoffTime *= backoffTime;
// spdlog::info("Attempt to reconnect in {}s...", backoffTime);
// std::this_thread::sleep_for(std::chrono::seconds(backoffTime));
// TCPSocket sock;
//
// retVal = sock.init(__sock.domain);
// if (retVal == INVALID_SOCKET || retVal == SOCKET_ERROR) {
// log::error("init()");
// continue;
// }
// retVal = sock.connect(__sock.remoteAddr);
// if (retVal == INVALID_SOCKET || retVal == SOCKET_ERROR) {
// log::error("connect()");
// continue;
// }
//
// return sock;
// }
// return TCPSocket();
//}
//
//int Session::recv(void* __restrict __buf, size_t __n, int __flags) {
// return -1;
//}
//
//int Session::send(const void* __buf, size_t __n, int __flags) {
// return -1;
//}
//
//}

View File

@@ -0,0 +1,2 @@
// #include "Session/SessionManager.hpp"
#include "precomp.hpp"

View File

@@ -55,11 +55,11 @@ void error(gsl::czstring msg) {
(LPSTR)&msgbuf,
0,
NULL);
spdlog::critical("[{}] {}", msg, msgbuf);
spdlog::error("[{}] {}", msg, msgbuf);
LocalFree(msgbuf);
#elif __linux__
gsl::czstring msgbuf = strerror(errno);
spdlog::critical("[{}] {}", msg, msgbuf);
spdlog::error("[{}] {}", msg, msgbuf);
#else
#error "이 플랫폼은 지원되지 않습니다."
#endif

View File

@@ -12,17 +12,16 @@ Socket::~Socket() {
destruct();
}
void Socket::init(int domain, int type, int protocol) {
if (domain == AF_INET)
bindAddr.length = sizeof(sockaddr_in);
else if (domain == AF_INET6)
bindAddr.length = sizeof(sockaddr_in6);
int Socket::init(int domain, int type, int protocol) {
this->domain = domain;
sock_ = ::socket(domain, type, protocol);
if (sock_ == INVALID_SOCKET)
log::critical("socket()");
valid_ = true;
return 0;
}
void Socket::destruct() {
@@ -33,6 +32,7 @@ void Socket::destruct() {
#elif __linux__
::close(sock_);
#endif
valid_ = false;
}
Socket::operator SOCKET() {
@@ -44,7 +44,7 @@ Socket::operator SOCKET() {
return INVALID_SOCKET;
}
void Socket::set(const SOCKET __sock) {
void Socket::set(const SOCKET __sock, int __domain) {
if (__sock == INVALID_SOCKET)
log::critical("socket()");
@@ -54,32 +54,12 @@ void Socket::set(const SOCKET __sock) {
valid_ = true;
};
void Socket::bind(sockaddr *__addr) {
bind((struct sockaddr *)__addr, sizeof(sockaddr));
}
void Socket::bind(sockaddr *__addr, socklen_t __len) {
bindAddr.length = __len;
std::memcpy(&bindAddr, __addr, __len);
int retVal = ::bind(sock_, __addr, __len);
int Socket::bind(Address __addr) {
bindAddr = __addr;
int retVal = ::bind(sock_, &__addr.addr, __addr.length);
if (retVal == INVALID_SOCKET)
log::critical("bind()");
}
void Socket::bind(sockaddr_in *__addr) {
bind((struct sockaddr *)__addr, sizeof(sockaddr_in));
}
void Socket::bind(sockaddr_in *__addr, socklen_t __len) {
bind((struct sockaddr *)__addr, __len);
}
void Socket::bind(sockaddr_in6 *__addr) {
bind((struct sockaddr *)__addr, sizeof(sockaddr_in6));
}
void Socket::bind(sockaddr_in6 *__addr, socklen_t __len) {
bind((struct sockaddr *)__addr, __len);
return retVal;
}
int Socket::recvfrom(void *__restrict __buf, size_t __n, int __flags, struct Address& __addr) {

View File

@@ -4,27 +4,29 @@
namespace Chattr {
void TCPSocket::init(int domain) {
init(domain, SOCK_STREAM, 0);
valid_ = true;
int TCPSocket::init(int domain) {
return init(domain, SOCK_STREAM, 0);
}
void TCPSocket::listen(int __n) {
int TCPSocket::listen(int __n) {
int retVal = ::listen(sock_, __n);
if (retVal == INVALID_SOCKET)
log::critical("listen()");
log::error("listen()");
return retVal;
}
void TCPSocket::accept(TCPSocket& newSock, Address& __addr) {
newSock.set(::accept(sock_, &__addr.addr, &__addr.length));
newSock.set(::accept(sock_, &__addr.addr, &__addr.length), domain);
if (newSock == INVALID_SOCKET)
log::critical("accept()");
log::error("accept()");
}
void TCPSocket::connect(Chattr::Address& serveraddr) {
int TCPSocket::connect(Address& serveraddr) {
int retVal = ::connect(sock_, (struct sockaddr *)&serveraddr.addr, serveraddr.length);
remoteAddr = serveraddr;
if (retVal == INVALID_SOCKET)
log::critical("connect()");
log::error("connect()");
return retVal;
}
int TCPSocket::recv(void *__restrict __buf, size_t __n, int __flags) {

View File

@@ -11,7 +11,7 @@ void StringTokenizer::set(gsl::czstring string, std::uint32_t size) {
bool token = false;
bool quote = false, doubleQuote = false;
for (int i = 0; i < size; i++) {
for (std::uint32_t i = 0; i < size; i++) {
if (string[i] == ' ' && token != true)
continue;

View File

@@ -29,13 +29,16 @@ enum class DataType : std::uint8_t {
class alignas(4) Packet {
public:
Packet() {
memset(serialized, 0, 1500);
}
union {
struct {
PacketType packetType;
RequestType requestType;
DataType dataType;
std::uint16_t packetLength;
std::uint8_t data[1484];
std::uint8_t data[1495];
} __data;
std::uint8_t serialized[1500];
};
@@ -90,6 +93,16 @@ public:
} __data;
std::uint8_t serialized[1500];
};
std::uint8_t* convToN() {
__data.packetLength = ::htons(__data.packetLength);
__data.roomCount = ::htonl(__data.roomCount);
return serialized;
}
std::uint8_t* convToH() {
__data.packetLength = ::ntohs(__data.packetLength);
__data.roomCount = ::ntohl(__data.roomCount);
return serialized;
}
};
class alignas(4) RoomJoinRequestPacket : public Packet {
@@ -128,7 +141,6 @@ public:
RequestType requestType;
DataType dataType;
std::uint16_t packetLength;
std::uint32_t usersCount;
std::uint8_t name[];
} __data;
std::uint8_t serialized[1500];
@@ -143,16 +155,31 @@ public:
RequestType requestType;
DataType dataType;
std::uint16_t packetLength;
std::uint8_t name[];
std::uint16_t destId[4];
std::uint8_t data[];
} __data;
std::uint8_t serialized[1500];
};
std::uint8_t* convToN() {
__data.packetLength = ::htons(__data.packetLength);
for (int i = 0; i < 4; i++)
__data.destId[i] = ::htons(__data.destId[i]);
return serialized;
}
std::uint8_t* convToH() {
__data.packetLength = ::ntohs(__data.packetLength);
for (int i = 0; i < 4; i++)
__data.destId[i] = ::ntohs(__data.destId[i]);
return serialized;
}
};
class alignas(4) ContinuePacket : public Packet {
public:
union {
struct {
PacketType packetType;
std::uint8_t padding[2];
std::uint16_t packetLength;
std::uint8_t data[];
} __data;
@@ -174,6 +201,41 @@ enum class ResponseStatusCode : std::uint16_t {
};
class alignas(4) ResponsePacket : public Packet {
public:
union {
struct {
PacketType packetType;
RequestType requestType;
DataType dataType;
std::uint16_t packetLength;
ResponseStatusCode responseStatusCode;
std::uint8_t data[];
} __data;
std::uint8_t serialized[1500];
};
std::uint8_t* convToN() {
__data.packetLength = ::htons(__data.packetLength);
__data.responseStatusCode = (ResponseStatusCode)::htons((std::uint16_t)__data.responseStatusCode);
return serialized;
}
std::uint8_t* convToH() {
__data.packetLength = ::ntohs(__data.packetLength);
__data.responseStatusCode = (ResponseStatusCode)::ntohs((std::uint16_t)__data.responseStatusCode);
return serialized;
}
};
//enum class RequestType : std::uint8_t {
// LOGIN,
// ROOM_CREATE,
// ROOM_LIST,
// ROOM_JOIN,
// ROOM_EXIT,
// USERS_LIST,
// DATA
//};
class alignas(4) LoginResponsePacket : public ResponsePacket {
public:
union {
struct {

View File

@@ -1,25 +0,0 @@
#pragma once
#include "Socket/TCPSocket.hpp"
#include "Utils/Snowflake.hpp"
#include <vector>
namespace Chattr {
class Session {
public:
Session(Chattr::TCPSocket __sock);
~Session();
void init(Chattr::TCPSocket __sock);
void destruct();
int send();
int recv();
Session(const Session&) = delete;
Session& operator=(Session&) = delete;
private:
Chattr::TCPSocket sock_;
struct Snowflake sessId_;
};
}

View File

@@ -9,7 +9,8 @@ public:
void init(std::shared_ptr<ThreadPool> __IOCPThread);
void recv();
int recv(void* __restrict __buf, size_t __n, int __flags);
int send(const void* __buf, size_t __n, int __flags);
private:
std::shared_ptr<ThreadPool> IOCPThread_;

View File

@@ -11,22 +11,13 @@ public:
Socket(int domain, int type, int protocol);
~Socket();
void init(int domain, int type, int protocol);
int init(int domain, int type, int protocol);
void destruct();
operator SOCKET();
void set(const SOCKET);
void set(const SOCKET __sock, int __domain);
void bind(sockaddr *__addr);
void bind(sockaddr *__addr, socklen_t __len);
//IPV4
void bind(sockaddr_in *__addr);
void bind(sockaddr_in *__addr, socklen_t __len);
//IPV6
void bind(sockaddr_in6 *__addr);
void bind(sockaddr_in6 *__addr, socklen_t __len);
int bind(Address __addr);
int recvfrom(void *__restrict __buf, size_t __n, int __flags, struct Address& __addr);
int sendto(const void *__buf, size_t __n, int __flags, struct Address __addr);
@@ -37,6 +28,9 @@ public:
Socket& operator=(Socket&&);
struct Address bindAddr = {};
struct Address remoteAddr = {};
int domain = 0;
protected:
bool valid_ = false;
SOCKET sock_ = INVALID_SOCKET;

View File

@@ -7,10 +7,10 @@ class TCPSocket : public Socket {
public:
using Socket::Socket;
using Socket::init;
void init(int domain);
void listen(int __n);
int init(int domain);
int listen(int __n);
void accept(TCPSocket& newSock, Address& addr);
void connect(Chattr::Address& serveraddr);
int connect(Chattr::Address& serveraddr);
int recv(void *__restrict __buf, size_t __n, int __flags);
int send(const void *__buf, size_t __n, int __flags);
};

View File

@@ -18,7 +18,7 @@ public:
void init(std::uint32_t numThreads);
template<typename _Callable, typename... _Args>
requires (!std::is_void_v<std::invoke_result_t<_Callable, _Args...>>)
requires (!std::is_void_v<std::invoke_result_t<_Callable, ThreadPool*, _Args...>>)
int enqueueJob(_Callable&& __job, std::invoke_result_t<_Callable, _Args...>& retVal, _Args&&... __args) {
if (terminate_) {
spdlog::error("Cannot run jobs on threads that terminating...");
@@ -26,8 +26,8 @@ public:
}
std::lock_guard<std::mutex> lock(jobQueueMutex);
auto boundFunc = [&retVal, __job = std::move(__job), ... __args = std::move(__args)]() mutable {
retVal = __job(std::move(__args)...);
auto boundFunc = [this, &retVal, __job = std::move(__job), ... __args = std::move(__args)]() mutable {
retVal = __job(this, std::move(__args)...);
};
auto task = std::packaged_task<void()>(std::move(boundFunc));
jobs_.push(std::move(task));
@@ -36,7 +36,7 @@ public:
return 0;
}
template<typename _Callable, typename... _Args>
requires std::is_void_v<std::invoke_result_t<_Callable, _Args...>>
requires std::is_void_v<std::invoke_result_t<_Callable, ThreadPool*, _Args...>>
int enqueueJob(_Callable&& __job, _Args&&... __args) {
if (terminate_) {
spdlog::error("Cannot run jobs on threads that terminating...");
@@ -44,8 +44,8 @@ public:
}
std::lock_guard<std::mutex> lock(jobQueueMutex);
auto boundFunc = [__job = std::move(__job), ... __args = std::move(__args)]() mutable {
__job(std::move(__args)...);
auto boundFunc = [this, __job = std::move(__job), ... __args = std::move(__args)]() mutable {
__job(this, std::move(__args)...);
};
auto task = std::packaged_task<void()>(std::move(boundFunc));
jobs_.push(std::move(task));

View File

@@ -19,5 +19,15 @@
#error "이 플랫폼은 지원되지 않습니다."
#endif
#include <chrono>
#include <gsl/gsl>
#include "spdlog/spdlog.h"
#include "spdlog/spdlog.h"
namespace Chattr {
struct _EPOQUE_ {
_EPOQUE_() {
EPOQUE = std::chrono::system_clock::now();
}
std::chrono::system_clock::time_point EPOQUE;
} _EPOQUE_;
}