diff --git a/Client/src/ClientManager/ClientManager.cpp b/Client/src/ClientManager/ClientManager.cpp index 85ec5bf..c48dac3 100644 --- a/Client/src/ClientManager/ClientManager.cpp +++ b/Client/src/ClientManager/ClientManager.cpp @@ -227,6 +227,7 @@ void ClientManager::sendMessage(Snowflake ID, std::string message) { int packetLength = dataPostPacket.__data.packetLength; data_->recvbytes = data_->sendbytes = 0; + data_->transferredbytes = 0; data_->wsabuf.len = data_->sendbytes = packetLength + 8; dataPostPacket.convToN(); @@ -245,6 +246,7 @@ void ClientManager::registerUser(std::string userName) { int packetLength = loginRequestPacket.__data.packetLength; data_->recvbytes = data_->sendbytes = 0; + data_->transferredbytes = 0; data_->wsabuf.len = packetLength + 8; loginRequestPacket.convToN(); @@ -263,6 +265,7 @@ void ClientManager::getUserList() { int packetLength = usersListRequestPacket.__data.packetLength; data_->recvbytes = data_->sendbytes = 0; + data_->transferredbytes = 0; data_->wsabuf.len = packetLength + 8; usersListRequestPacket.convToN(); diff --git a/impl/Socket/IOCP.cpp b/impl/Socket/IOCP.cpp index a9a4452..213d8f6 100644 --- a/impl/Socket/IOCP.cpp +++ b/impl/Socket/IOCP.cpp @@ -26,9 +26,9 @@ void IOCP::registerSocket(IOCPPASSINDATA* data) { if (returnData == 0) completionPort_ = returnData; #elif __linux__ - // int flags = ::fcntl(data->socket->sock, F_GETFL); - // flags |= O_NONBLOCK; - // fcntl(data->socket->sock, F_SETFL, flags); + int flags = ::fcntl(data->socket->sock, F_GETFL); + flags |= O_NONBLOCK; + fcntl(data->socket->sock, F_SETFL, flags); struct epoll_event ev; ev.events = EPOLLIN | EPOLLONESHOT; diff --git a/include/Socket/IOCP.hpp b/include/Socket/IOCP.hpp index b7b03ab..67e5c56 100644 --- a/include/Socket/IOCP.hpp +++ b/include/Socket/IOCP.hpp @@ -80,8 +80,28 @@ public: IOCPPASSINDATA* rootIocpData = (IOCPPASSINDATA*)event.data.ptr; std::lock_guard lock(rootIocpData->socket->readMutex); - char peekBuffer[1]; - while (rootIocpData->socket->recv(peekBuffer, 1, MSG_PEEK)) { + while (true) { + char peekBuffer[1]; + int rc = rootIocpData->socket->recv(peekBuffer, 1, MSG_PEEK); + if (rc > 0); + else if (rc == 0) { + spdlog::debug("Client disconnected. [{}]", (std::string)(rootIocpData->socket->remoteAddr)); + ::epoll_ctl(epollfd, EPOLL_CTL_DEL, rootIocpData->socket->sock, NULL); + delete rootIocpData; + return; + } + else { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + spdlog::trace("No data to read on {}", tid); + return; + } + else { + spdlog::error("recv() [{}]", strerror(errno)); + ::epoll_ctl(epollfd, EPOLL_CTL_DEL, rootIocpData->socket->sock, NULL); + delete rootIocpData; + return; + } + } Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; ::memcpy(ptr, rootIocpData, sizeof(IOCPPASSINDATA)); ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); @@ -180,7 +200,7 @@ public: pthread_t tid = pthread_self(); spdlog::trace("epoll waiting on {}", tid); - int nready = ::epoll_wait(epollfd, events, FD_SETSIZE, -1); + int nready = ::epoll_wait(epollfd, events, FD_SETSIZE, 1000); for (int i=0; i