diff --git a/Server/include/ServerManager/ServerManager.hpp b/Server/include/ServerManager/ServerManager.hpp index 217f2ef..e210f3c 100644 --- a/Server/include/ServerManager/ServerManager.hpp +++ b/Server/include/ServerManager/ServerManager.hpp @@ -40,6 +40,15 @@ public: }); } + void processLoginRequestPacket(LoginRequestPacket loginRequestPacket, IOCPPASSINDATA* data); + void processRoomCreateRequestPacket(RoomCreateRequestPacket roomCreateRequestPacket, IOCPPASSINDATA* data); + void processRoomListRequest(RoomListRequestPacket roomListRequestPacket, IOCPPASSINDATA* data); + void processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinRequestPacket, IOCPPASSINDATA* data); + void processRoomExitRequestPacket(RoomExitRequestPacket roomExitRequestPacket, IOCPPASSINDATA* data); + void processUsersListRequestPacket(UsersListRequestPacket usersListRequestPacket, IOCPPASSINDATA* data); + void processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data); + void processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data); + void registerUser(std::string userName, std::shared_ptr sock); void deleteUser(Snowflake UID); std::vector> getUserList(); diff --git a/Server/src/ServerManager/ServerManager.cpp b/Server/src/ServerManager/ServerManager.cpp index cbc305e..47534de 100644 --- a/Server/src/ServerManager/ServerManager.cpp +++ b/Server/src/ServerManager/ServerManager.cpp @@ -8,175 +8,99 @@ void ServerManager::_IOCPClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDA Chattr::Packet pack; int packetSize = data->transferredbytes; - if (data->recvbytes == 0) { - data->recvbytes = data->transferredbytes; - data->transferredbytes = 0; - } - else if (data->transferredbytes <= data->sendbytes) { + if (data->event == IOCPEVENT::WRITE && data->transferredbytes >= data->wsabuf.len) { + data->event = IOCPEVENT::READ; + data->wsabuf.len = 1500; data->IOCPInstance->recv(data, 1); return; } memcpy(pack.serialized, data->wsabuf.buf, data->wsabuf.len); - DataPostPacket dataPostPacket; - ResponsePacket responsePacket; + std::uint16_t packetLength = ::ntohs(pack.__data.packetLength); + + if (data->event == IOCPEVENT::READ && data->transferredbytes < packetLength + 8) { + data->IOCPInstance->recv(data, 1); + data->wsabuf.len = 1500; + return; + } pack.convToH(); - - std::uint16_t packetLength = pack.__data.packetLength; - - switch (packetParser(pack)) { + PacketSet packetSet = packetParser(pack); + pack.convToN(); + switch (packetSet) { case PacketSet::LOGINREQUEST: { - pack.convToN(); LoginRequestPacket loginRequestPacket; - std::memcpy(&loginRequestPacket.serialized, &pack, 8 + packetLength); + std::memcpy(&loginRequestPacket.serialized, pack.serialized, 8 + packetLength); loginRequestPacket.convToH(); - - std::string userName( - (char*)loginRequestPacket.__data.data, - loginRequestPacket.__data.packetLength); - registerUser(userName, data->socket); - - LoginResponsePacket loginResponsePacket; - loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN; - loginResponsePacket.__data.dataType = Chattr::DataType::TEXT; - loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); - loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - Snowflake yourId = userSocket2UID_[data->socket]; - ::memcpy(loginResponsePacket.__data.yourId, &yourId, sizeof(Snowflake)); - - loginResponsePacket.convToN(); - memcpy(data->wsabuf.buf, loginResponsePacket.serialized, 16); - data->sendbytes = 16; - data->transferredbytes = 16; - data->wsabuf.len = 16; - data->IOCPInstance->send(data, 1, 0); + processLoginRequestPacket(loginRequestPacket, data); } break; - case PacketSet::ROOMCREATEREQUEST: + case PacketSet::ROOMCREATEREQUEST: { + RoomCreateRequestPacket roomCreateRequestPacket; + std::memcpy(&roomCreateRequestPacket.serialized, pack.serialized, 8 + packetLength); + roomCreateRequestPacket.convToH(); + processRoomCreateRequestPacket(roomCreateRequestPacket, data); + } break; - case PacketSet::ROOMLISTREQUEST: + case PacketSet::ROOMLISTREQUEST: { + RoomListRequestPacket roomListRequestPacket; + std::memcpy(&roomListRequestPacket.serialized, pack.serialized, 8 + packetLength); + roomListRequestPacket.convToH(); + processRoomListRequest(roomListRequestPacket, data); + } break; - case PacketSet::ROOMJOINREQUEST: + case PacketSet::ROOMJOINREQUEST: { + RoomJoinRequestPacket roomJoinRequestPacket; + std::memcpy(&roomJoinRequestPacket.serialized, pack.serialized, 8 + packetLength); + roomJoinRequestPacket.convToH(); + processRoomJoinRequestPacket(roomJoinRequestPacket, data); + } break; - case PacketSet::ROOMEXITREQUEST: + case PacketSet::ROOMEXITREQUEST: { + RoomExitRequestPacket roomExitRequestPacket; + std::memcpy(&roomExitRequestPacket.serialized, pack.serialized, 8 + packetLength); + roomExitRequestPacket.convToH(); + processRoomExitRequestPacket(roomExitRequestPacket, data); + } break; case PacketSet::USERSLISTREQUEST: { - pack.convToN(); UsersListRequestPacket usersListRequestPacket; - std::memcpy(&usersListRequestPacket.serialized, &pack, 8 + packetLength); + std::memcpy(&usersListRequestPacket.serialized, pack.serialized, 8 + packetLength); usersListRequestPacket.convToH(); - - auto usersList = getUserList(); - - for (auto user : usersList) { - UsersListResponsePacket usersListResponsePacket; - usersListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - usersListResponsePacket.__data.requestType = Chattr::RequestType::USERS_LIST; - usersListResponsePacket.__data.dataType = Chattr::DataType::BINARY; - usersListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + user.second.size(); - usersListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - usersListResponsePacket.__data.usersCount = usersList.size(); - ::memcpy(usersListResponsePacket.__data.userId, &user.first, sizeof(Snowflake)); - ::memcpy(usersListResponsePacket.__data.name, user.second.c_str(), user.second.size()); - - int sendPacketLength = usersListResponsePacket.__data.packetLength; - - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - ptr->socket = data->socket; - ptr->recvbytes = ptr->sendbytes = 0; - ptr->wsabuf.buf = ptr->buf; - ptr->wsabuf.len = 1500; - ptr->IOCPInstance = data->IOCPInstance; - - usersListResponsePacket.convToN(); - memcpy(ptr->wsabuf.buf, usersListResponsePacket.serialized, sendPacketLength + 8); - data->sendbytes = sendPacketLength + 8; - data->transferredbytes = sendPacketLength + 8; - data->wsabuf.len = sendPacketLength + 8; - data->IOCPInstance->send(ptr, 1, 0); - } + processUsersListRequestPacket(usersListRequestPacket, data); } break; - case PacketSet::DATAPOSTTEXT: { - pack.convToN(); - std::memcpy(&dataPostPacket.serialized, &pack, 8 + packetLength); + case PacketSet::DATAPOST: { + DataPostPacket dataPostPacket; + std::memcpy(&dataPostPacket.serialized, &pack.serialized, 8 + packetLength); dataPostPacket.convToH(); - - Snowflake destID = {}; - - ::memcpy(&destID.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); - - std::vector> destinationSockets; - - if (userNames_.find(destID) != userNames_.end()) - destinationSockets.push_back(UID2userSocket_[destID]); - else - for (auto user : rooms_[destID]) - destinationSockets.push_back(user.second); - - spdlog::info("Received [{}] from : [{}] to : [{}]", - std::string((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)), - (std::string)data->socket->remoteAddr, - destID.snowflake); - + processDataPostPacket(dataPostPacket, data); + } + break; + case PacketSet::CONTINUE: { + ContinuePacket continuePacket; + std::memcpy(&continuePacket.serialized, &pack.serialized, 8 + packetLength); + continuePacket.convToH(); + processContinuePacket(continuePacket, data); + } + break; + case PacketSet::INVALID: + default: { + ResponsePacket responsePacket; responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; responsePacket.__data.requestType = Chattr::RequestType::DATA; responsePacket.__data.dataType = Chattr::DataType::TEXT; responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; responsePacket.convToN(); memcpy(data->wsabuf.buf, responsePacket.serialized, 10); data->sendbytes = 10; - data->transferredbytes = 10; data->wsabuf.len = 10; data->IOCPInstance->send(data, 1, 0); - - for (auto dest : destinationSockets) { - dataPostPacket.__data.packetType = Chattr::PacketCategory::PACKET_POST; - dataPostPacket.__data.requestType = Chattr::RequestType::DATA; - dataPostPacket.__data.dataType = Chattr::DataType::TEXT; - - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - ptr->socket = dest; - ptr->recvbytes = ptr->sendbytes = 0; - ptr->wsabuf.buf = ptr->buf; - ptr->wsabuf.len = 1500; - ptr->IOCPInstance = data->IOCPInstance; - - dataPostPacket.convToN(); - memcpy(ptr->wsabuf.buf, dataPostPacket.serialized, packetLength + 6); - data->sendbytes = packetLength + 6; - data->transferredbytes = packetLength + 6; - data->wsabuf.len = packetLength + 6; - data->IOCPInstance->send(ptr, 1, 0); - } } break; - case PacketSet::DATAPOSTBINARY: - break; - case PacketSet::CONTINUE: - break; - case PacketSet::INVALID: - default: - responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - responsePacket.__data.requestType = Chattr::RequestType::DATA; - responsePacket.__data.dataType = Chattr::DataType::TEXT; - responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::BAD_REQUEST; - - responsePacket.convToN(); - memcpy(data->wsabuf.buf, responsePacket.serialized, 10); - data->sendbytes = 10; - data->transferredbytes = 10; - data->wsabuf.len = 10; - data->IOCPInstance->send(data, 1, 0); - break; } } @@ -191,9 +115,8 @@ PacketSet ServerManager::packetParser(Packet Packet) { } switch (Packet.__data.dataType) { case DataType::TEXT: - return PacketSet::DATAPOSTTEXT; case DataType::BINARY: - return PacketSet::DATAPOSTBINARY; + return PacketSet::DATAPOST; default: return PacketSet::INVALID; } @@ -243,6 +166,123 @@ PacketSet ServerManager::packetParser(Packet Packet) { return PacketSet::INVALID; } +void ServerManager::processLoginRequestPacket(LoginRequestPacket loginRequestPacket, Chattr::IOCPPASSINDATA* data) { + std::string userName( + (char*)loginRequestPacket.__data.data, + loginRequestPacket.__data.packetLength); + registerUser(userName, data->socket); + + LoginResponsePacket loginResponsePacket; + loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; + loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN; + loginResponsePacket.__data.dataType = Chattr::DataType::TEXT; + loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); + loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + Snowflake yourId = userSocket2UID_[data->socket]; + ::memcpy(loginResponsePacket.__data.yourId, &yourId, sizeof(Snowflake)); + + loginResponsePacket.convToN(); + memcpy(data->wsabuf.buf, loginResponsePacket.serialized, 16); + data->sendbytes = 16; + data->wsabuf.len = 16; + data->IOCPInstance->send(data, 1, 0); +} + +void ServerManager::processRoomCreateRequestPacket(RoomCreateRequestPacket roomCreateRequestPacket, Chattr::IOCPPASSINDATA* data) { +} + +void ServerManager::processRoomListRequest(RoomListRequestPacket roomListRequestPacket, Chattr::IOCPPASSINDATA* data) { +} + +void ServerManager::processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinRequestPacket, Chattr::IOCPPASSINDATA* data) { +} + +void ServerManager::processRoomExitRequestPacket(RoomExitRequestPacket roomExitRequestPacket, Chattr::IOCPPASSINDATA* data) { +} + +void ServerManager::processUsersListRequestPacket(UsersListRequestPacket usersListRequestPacket, Chattr::IOCPPASSINDATA* data) { + auto usersList = getUserList(); + + for (auto user : usersList) { + UsersListResponsePacket usersListResponsePacket; + usersListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; + usersListResponsePacket.__data.requestType = Chattr::RequestType::USERS_LIST; + usersListResponsePacket.__data.dataType = Chattr::DataType::BINARY; + usersListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + user.second.size(); + usersListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + usersListResponsePacket.__data.usersCount = usersList.size(); + ::memcpy(usersListResponsePacket.__data.userId, &user.first, sizeof(Snowflake)); + ::memcpy(usersListResponsePacket.__data.name, user.second.c_str(), user.second.size()); + + int packetLength = usersListResponsePacket.__data.packetLength; + + Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; + ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); + ptr->socket = data->socket; + ptr->recvbytes = ptr->sendbytes = 0; + ptr->wsabuf.buf = ptr->buf; + ptr->wsabuf.len = packetLength + 8; + ptr->IOCPInstance = data->IOCPInstance; + + usersListResponsePacket.convToN(); + memcpy(ptr->wsabuf.buf, usersListResponsePacket.serialized, packetLength + 8); + data->sendbytes = packetLength + 8; + data->IOCPInstance->send(ptr, 1, 0); + } +} + +void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data) { + Snowflake destID; + ::memcpy(&destID.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); + + std::vector> destinationSockets; + + if (userNames_.find(destID) != userNames_.end()) + destinationSockets.push_back(UID2userSocket_[destID]); + else + for (auto user : rooms_[destID]) + destinationSockets.push_back(user.second); + + spdlog::info("Received [{}] from : [{}] to : [{}]", + std::string((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)), + (std::string)data->socket->remoteAddr, + destID.snowflake); + + ResponsePacket responsePacket; + responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; + responsePacket.__data.requestType = Chattr::RequestType::DATA; + responsePacket.__data.dataType = Chattr::DataType::TEXT; + responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); + responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + + responsePacket.convToN(); + memcpy(data->wsabuf.buf, responsePacket.serialized, 10); + data->sendbytes = 10; + data->wsabuf.len = 10; + data->IOCPInstance->send(data, 1, 0); + + int packetLength = dataPostPacket.__data.packetLength; + + for (auto dest : destinationSockets) { + + Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; + ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); + ptr->socket = dest; + ptr->recvbytes = ptr->sendbytes = 0; + ptr->wsabuf.buf = ptr->buf; + ptr->wsabuf.len = packetLength + 6; + ptr->IOCPInstance = data->IOCPInstance; + + dataPostPacket.convToN(); + memcpy(ptr->wsabuf.buf, dataPostPacket.serialized, packetLength + 6); + data->sendbytes = packetLength + 6; + data->IOCPInstance->send(ptr, 1, 0); + } +} + +void ServerManager::processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data) { +} + void ServerManager::registerUser(std::string userName, std::shared_ptr sock) { std::lock_guard lock(resourceMutex_); Snowflake UID = GenerateID(); diff --git a/impl/Socket/IOCP.cpp b/impl/Socket/IOCP.cpp index 7f3c9fb..fd1f756 100644 --- a/impl/Socket/IOCP.cpp +++ b/impl/Socket/IOCP.cpp @@ -25,6 +25,7 @@ void IOCP::registerSocket(Chattr::IOCPPASSINDATA* data) { } int IOCP::recv(Chattr::IOCPPASSINDATA* data, int bufferCount) { + data->event = IOCPEVENT::READ; #ifdef _WIN32 DWORD recvbytes = 0, flags = 0; return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, &flags, &data->overlapped, NULL); @@ -37,6 +38,7 @@ int IOCP::recv(Chattr::IOCPPASSINDATA* data, int bufferCount) { } int IOCP::send(Chattr::IOCPPASSINDATA* data, int bufferCount, int __flags) { + data->event = IOCPEVENT::WRITE; #ifdef _WIN32 DWORD sendbytes = 0; return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, __flags, &data->overlapped, NULL); diff --git a/include/Packet/Packet.hpp b/include/Packet/Packet.hpp index 67ca1cf..e517fad 100644 --- a/include/Packet/Packet.hpp +++ b/include/Packet/Packet.hpp @@ -12,8 +12,7 @@ enum class PacketSet { ROOMJOINREQUEST, ROOMEXITREQUEST, USERSLISTREQUEST, - DATAPOSTTEXT, - DATAPOSTBINARY, + DATAPOST, CONTINUE, RESPONSE, LOGINRESPONSE, diff --git a/include/Socket/IOCP.hpp b/include/Socket/IOCP.hpp index 4a5dca8..345e598 100644 --- a/include/Socket/IOCP.hpp +++ b/include/Socket/IOCP.hpp @@ -26,8 +26,15 @@ namespace Chattr { class IOCP; +enum class IOCPEVENT { + ERR, + READ, + WRITE +}; + struct IOCPPASSINDATA { OVERLAPPED overlapped; + IOCPEVENT event; std::shared_ptr socket; char buf[1501]; std::uint32_t recvbytes;