#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 _TCPRecvClient(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, _TCPRecvClient); // struct Chattr::WSAManager wsaManager; 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); DWORD recvbytes = 0, flags = 0; while (true) { spdlog::info("Waiting for connection..."); sock.accept(clientSock, clientAddr); Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; ZeroMemory(&ptr->overlapped, sizeof(OVERLAPPED)); ptr->socket = std::move(clientSock); ptr->recvbytes = ptr->sendbytes = 0; ptr->wsabuf.buf = ptr->buf; ptr->wsabuf.len = 1500; iocp.registerSocket(ptr->socket.sock); int returnData = WSARecv(ptr->socket.sock, &ptr->wsabuf, 1, &recvbytes, &flags, &ptr->overlapped, NULL); } } void _TCPRecvClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDATA* data) { #ifdef _WIN32 DWORD tid = GetCurrentThreadId(); #elif __linux__ pthread_t tid = pthread_self(); #endif spdlog::info("entered recvfunc on TID: {}", tid); Chattr::Packet pack; int packetSize = 1500; int totalRedSize = 0; int redSize = 0; // spdlog::info("Receving from: [{}]", (std::string)sock.remoteAddr); //while (totalRedSize < packetSize) { // redSize = data->socket.recv(&pack.serialized, 1500 - totalRedSize, 0); // // if (redSize <= 0) { // // spdlog::info("Client disconnected. [{}]", (std::string)sock.remoteAddr); // return; // } // totalRedSize += redSize; //} 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 : [{}]", totalRedSize, 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; } Sleep(10000); /*if (packetError) { thread->enqueueJob(_TCPRecvClient, data);; } else thread->enqueueJob(_TCPRecvClient, 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);*/ }