From 6428db9d31083a78a1f8b9050158b212bb152cd6 Mon Sep 17 00:00:00 2001 From: HappyTanuki Date: Thu, 5 Jun 2025 02:12:50 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=BD=EA=B8=B0/=EC=93=B0=EA=B8=B0=20socket?= =?UTF-8?q?=20=EB=B9=84=EB=8F=99=EA=B8=B0=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/src/asteroid/main.cpp | 9 +++++---- impl/socket/iocp.cpp | 21 ++++++++++++++------ include/socket/iocp.h | 37 ++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Client/src/asteroid/main.cpp b/Client/src/asteroid/main.cpp index ac4ecf9..3afaaa4 100644 --- a/Client/src/asteroid/main.cpp +++ b/Client/src/asteroid/main.cpp @@ -4,6 +4,7 @@ #include "glfw/glfw_window.h" #include "socket/iocp.h" #include "socket/tcp_socket.h" +#include "socket/udp_socket.h" #include "socket/wsa_manager.h" #include "utils/log.h" #include "vulkan_engine/vulkan/engine.h" @@ -17,7 +18,7 @@ #endif utils::ThreadPool tp(0); Network::IOCP iocp; - iocp.init(&tp, SessionProtocol::TCP); + iocp.init(&tp, SessionProtocol::TLS); Network::Address addr; in6_addr in6addr; @@ -45,12 +46,12 @@ send_data.push_back(data); iocp.send(sock.sock, &send_data); - Sleep(10000); - Network::IOCPPASSINDATA* recv_data = new Network::IOCPPASSINDATA(16 * 1024); recv_data->socket = std::make_shared(sock); recv_data->IOCPInstance = &iocp; - iocp.recv(recv_data); + while (!iocp.recv(recv_data)); // 어떤 데이터를 읽는걸 보장받고 싶다면 그냥 스린락 걸어버리기. + + spdlog::info("recv_data: {}", recv_data->wsabuf.buf); const veng::GlfwInitialization _glfw; diff --git a/impl/socket/iocp.cpp b/impl/socket/iocp.cpp index 833835d..b627e3a 100644 --- a/impl/socket/iocp.cpp +++ b/impl/socket/iocp.cpp @@ -23,10 +23,19 @@ void IOCP::registerSocket(IOCPPASSINDATA* data) { (HANDLE)data->socket->sock, completionPort_, data->socket->sock, 0); if (returnData == 0) completionPort_ = returnData; - data->event = IOCPEVENT::READ; + IOCPPASSINDATA* recv_data = new IOCPPASSINDATA(data->bufsize); + recv_data->event = IOCPEVENT::READ; + recv_data->socket = data->socket; DWORD recvbytes = 0, flags = 0; - ::WSARecv(data->socket->sock, &data->wsabuf, 1, &recvbytes, &flags, - &data->overlapped, NULL); + int result = ::WSARecv(recv_data->socket->sock, &recv_data->wsabuf, 1, + &recvbytes, &flags, &recv_data->overlapped, NULL); + if (result == SOCKET_ERROR) { + int err = ::WSAGetLastError(); + if (err != WSA_IO_PENDING) { + spdlog::error("WSARecv failed: {}", err); + // 반드시 여기서 리턴하거나 처리해야 합니다. + } + } #endif } @@ -131,9 +140,9 @@ void IOCP::packet_sender_(SOCKET sock) { int data_len = 0; if (proto_ == SessionProtocol::TLS || proto_ == SessionProtocol::QUIC) { - int ret = ::SSL_write(front->ssl, front->wsabuf.buf, front->wsabuf.len); + int ret = ::SSL_write(front->ssl.get(), front->wsabuf.buf, front->wsabuf.len); if (ret <= 0) { - int err = ::SSL_get_error(front->ssl, ret); + int err = ::SSL_get_error(front->ssl.get(), ret); if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { queue->push_front(front); break; @@ -143,7 +152,7 @@ void IOCP::packet_sender_(SOCKET sock) { break; } - while ((data_len = ::BIO_read(front->wbio, buf.data(), buf.size())) > 0) { + while ((data_len = ::BIO_read(::SSL_get_wbio(front->ssl.get()), buf.data(), buf.size())) > 0) { wsabuf.buf = buf.data(); wsabuf.len = data_len; diff --git a/include/socket/iocp.h b/include/socket/iocp.h index aeeccec..8ca34fa 100644 --- a/include/socket/iocp.h +++ b/include/socket/iocp.h @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include "socket.h" #include "utils/thread_pool.h" @@ -31,13 +31,11 @@ class IOCP; enum class IOCPEVENT { QUIT, READ, WRITE }; -struct IOCPPASSINDATA { // 얘 double free 문제 있음.. +struct IOCPPASSINDATA { OVERLAPPED overlapped; IOCPEVENT event; std::shared_ptr socket; - SSL* ssl; - BIO* rbio; // bio는 ssl별로 달라야 하므로 분리해야 함.. - BIO* wbio; + std::shared_ptr ssl; std::uint32_t transferredbytes; WSABUF wsabuf; std::uint32_t bufsize; @@ -50,8 +48,7 @@ struct IOCPPASSINDATA { // 얘 double free 문제 있음.. std::memset(&overlapped, 0, sizeof(overlapped)); event = IOCPEVENT::QUIT; socket = nullptr; - rbio = nullptr; - wbio = nullptr; + ssl = nullptr; transferredbytes = 0; this->bufsize = bufsize; IOCPInstance = nullptr; @@ -63,10 +60,9 @@ struct IOCPPASSINDATA { // 얘 double free 문제 있음.. std::memset(&overlapped, 0, sizeof(overlapped)); event = IOCPEVENT::QUIT; socket = nullptr; - ssl = ::SSL_new(ctx); - rbio = ::BIO_new(::BIO_s_mem()); - wbio = ::BIO_new(::BIO_s_mem()); - ::SSL_set_bio(ssl, rbio, wbio); + ssl = std::make_shared(::SSL_new(ctx), ::SSL_free); + ::SSL_set_bio(ssl.get(), ::BIO_new(::BIO_s_mem()), + ::BIO_new(::BIO_s_mem())); transferredbytes = 0; this->bufsize = bufsize; IOCPInstance = nullptr; @@ -80,8 +76,6 @@ struct IOCPPASSINDATA { // 얘 double free 문제 있음.. std::memset(&overlapped, 0, sizeof(overlapped)); event = other.event; socket = other.socket; - rbio = other.rbio; - wbio = other.wbio; transferredbytes = other.transferredbytes; bufsize = other.bufsize; IOCPInstance = other.IOCPInstance; @@ -104,8 +98,6 @@ struct IOCPPASSINDATA { // 얘 double free 문제 있음.. std::memset(&overlapped, 0, sizeof(overlapped)); event = other.event; socket = other.socket; - rbio = other.rbio; - wbio = other.wbio; transferredbytes = other.transferredbytes; bufsize = other.bufsize; IOCPInstance = other.IOCPInstance; @@ -190,9 +182,11 @@ class IOCP { auto queue_list = GetRecvQueue_(data->socket->sock); if (data->event == IOCPEVENT::READ) { if (proto_ == SessionProtocol::TLS || proto_ == SessionProtocol::QUIC) { - ::BIO_write(data->rbio, data->wsabuf.buf, cbTransfrred); + ::BIO_write(::SSL_get_rbio(data->ssl.get()), data->wsabuf.buf, + cbTransfrred); - while ((red_data = ::SSL_read(data->ssl, buf.data(), buf.size())) > 0) { + while ((red_data = + ::SSL_read(data->ssl.get(), buf.data(), buf.size())) > 0) { queue_list->emplace_back(std::make_pair( std::vector(buf.begin(), buf.begin() + red_data), 0)); } @@ -204,8 +198,13 @@ class IOCP { 0)); } DWORD recvbytes = 0, flags = 0; - ::WSARecv(data->socket->sock, &data->wsabuf, 1, &recvbytes, &flags, - &data->overlapped, NULL); + + IOCPPASSINDATA* recv_data = new IOCPPASSINDATA(data->bufsize); + recv_data->socket = data->socket; + + delete data; + ::WSARecv(recv_data->socket->sock, &recv_data->wsabuf, 1, &recvbytes, + &flags, &recv_data->overlapped, NULL); } else { // WRITE 시, 무시한다. delete data; }