#include "Socket/TCPSocket.hpp" #include "Socket/Log.hpp" #include "Socket/WSAManager.hpp" #include "Utils/ConfigManager.hpp" #include "Utils/Thread.hpp" #include "Utils/ThreadPool.hpp" #include "Utils/StringTokenizer.hpp" #include "Utils/Snowflake.hpp" #include "Socket/IOCP.hpp" #include "Packet/Packet.hpp" #include #include #include "precomp.hpp" void _IOCPClient(Chattr::ThreadPool* threadPool, Chattr::IOCPPASSINDATA* data); void _TCPSendClient(Chattr::ThreadPool* threadPool, Chattr::TCPSocket sock, std::queue packets); int main() { auto config = Chattr::ConfigManager::load(); Chattr::log::setDefaultLogger(config.logLevel, config.logFileName, config.logfileSize, config.logfileCount); Chattr::ThreadPool threadPool(0); Chattr::IOCP iocp; iocp.init(&threadPool, _IOCPClient); Chattr::TCPSocket sock; struct Chattr::Address serveraddr; Chattr::TCPSocket clientSock; struct Chattr::Address clientAddr; if (config.ipVersion == 4) { sock.init(AF_INET); serveraddr.set(AF_INET, INADDR_ANY, config.listenPort); clientAddr.setType(AF_INET); } else if (config.ipVersion == 6) { sock.init(AF_INET6); serveraddr.set(AF_INET6, in6addr_any, config.listenPort); clientAddr.setType(AF_INET6); } sock.bind(serveraddr); sock.listen(SOMAXCONN); #ifdef _WIN32 DWORD pid = GetCurrentProcessId(); #elif __linux__ pid_t pid = getpid(); #endif spdlog::debug("PID : {}", pid); while (true) { spdlog::info("Waiting for connection..."); sock.accept(clientSock, clientAddr); bool enable = true; clientSock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, (const char *)&enable, sizeof(enable)); Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); ptr->socket = std::move(clientSock); ptr->recvbytes = ptr->sendbytes = 0; ptr->wsabuf.buf = ptr->buf; ptr->wsabuf.len = 1500; ptr->IOCPInstance = &iocp; iocp.registerSocket(ptr); int returnData = iocp.recv(ptr); } } void _IOCPClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDATA* data) { Chattr::Packet pack; int packetSize = 1500; int totalRedSize = 0; int redSize = 0; if (data->wsabuf.len == data->sendbytes) return; memcpy(pack.serialized, data->wsabuf.buf, data->wsabuf.len); std::string recvString; bool packetError = false; Chattr::DataPostPacket dataPostPacket; Chattr::ResponsePacket packet; std::queue responsePackets; switch (pack.__data.packetType) { case Chattr::PacketType::PACKET_POST: if (pack.__data.requestType != Chattr::RequestType::DATA){ packetError = true; break; } switch (pack.__data.dataType) { case Chattr::DataType::TEXT: std::memcpy(&dataPostPacket.serialized, &pack, 1500); dataPostPacket.convToH(); dataPostPacket.__data.packetLength = (dataPostPacket.__data.packetLength > 1487) ? 1487 : dataPostPacket.__data.packetLength; recvString = std::string((char *)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t)*4)); spdlog::info("Red size : {}, {} from : [{}]", data->wsabuf.len, recvString, (std::string)data->socket.remoteAddr); break; case Chattr::DataType::BINARY: break; default: packet.__data.packetType = Chattr::PacketType::PACKET_RESPONSE; packet.__data.requestType = Chattr::RequestType::DATA; packet.__data.dataType = Chattr::DataType::TEXT; packet.__data.packetLength = sizeof(Chattr::ResponseStatusCode); packet.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; packet.convToN(); responsePackets.push(packet); 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: packet.__data.packetType = Chattr::PacketType::PACKET_RESPONSE; packet.__data.requestType = Chattr::RequestType::DATA; packet.__data.dataType = Chattr::DataType::TEXT; packet.__data.packetLength = sizeof(Chattr::ResponseStatusCode); packet.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; packet.convToN(); responsePackets.push(packet); packetError = true; break; } break; case Chattr::PacketType::PACKET_CONTINUE: break; default: packet.__data.packetType = Chattr::PacketType::PACKET_RESPONSE; packet.__data.requestType = Chattr::RequestType::DATA; packet.__data.dataType = Chattr::DataType::TEXT; packet.__data.packetLength = sizeof(Chattr::ResponseStatusCode); packet.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; packet.convToN(); responsePackets.push(packet); packetError = true; break; } packet.__data.packetType = Chattr::PacketType::PACKET_RESPONSE; packet.__data.requestType = Chattr::RequestType::DATA; packet.__data.dataType = Chattr::DataType::TEXT; packet.__data.packetLength = sizeof(Chattr::ResponseStatusCode); packet.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; packet.convToN(); memcpy(data->wsabuf.buf, packet.serialized, data->wsabuf.len); int returnData = data->IOCPInstance->send(data, 0); // int returnData = data->IOCPInstance->recv(data); } void _TCPSendClient(Chattr::ThreadPool* thread, Chattr::TCPSocket sock, std::queue packets) { Chattr::ResponsePacket pack = packets.front(); packets.pop(); int packetSize = 1500; int totalSentSize = 0; int sentSize = 0; spdlog::info("Sending to: [{}]", (std::string)sock.remoteAddr); while (totalSentSize < packetSize) { sentSize = sock.send(&pack.serialized, 1500 - totalSentSize, 0); if (sentSize <= 0) { spdlog::info("Client disconnected. [{}]", (std::string)sock.remoteAddr); return; } totalSentSize += sentSize; } /*if (packets.empty()) thread->enqueueJob(_TCPRecvClient, std::move(sock)); else thread->enqueueJob(_TCPSendClient, std::move(sock), packets);*/ }