Files
NP_Midterm/Server/src/server.cpp

205 lines
7.0 KiB
C++

#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 <iostream>
#include <bitset>
#include "precomp.hpp"
void _TCPRecvClient(Chattr::ThreadPool* threadPool, Chattr::IOCPPASSINDATA* data);
void _TCPSendClient(Chattr::ThreadPool* threadPool, Chattr::TCPSocket sock, std::queue<Chattr::ResponsePacket> 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<Chattr::ResponsePacket> 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<Chattr::ResponsePacket> 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);*/
}