From f9451b163128bebb9eb1f6e693c692e542718e0a Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 22 Nov 2025 02:39:38 -0500 Subject: [PATCH 1/6] try to improve error handling --- src/ActiveSocket.cpp | 38 ++-- src/Host.h | 12 ++ src/PassiveSocket.cpp | 142 ++++++--------- src/SimpleSocket.cpp | 409 ++++++++++++++++++------------------------ src/SimpleSocket.h | 16 +- 5 files changed, 271 insertions(+), 346 deletions(-) diff --git a/src/ActiveSocket.cpp b/src/ActiveSocket.cpp index 3dd5b12..a1ef62b 100644 --- a/src/ActiveSocket.cpp +++ b/src/ActiveSocket.cpp @@ -133,7 +133,6 @@ bool CActiveSocket::ConnectTCP(const char *pAddr, uint16 nPort) //------------------------------------------------------------------------------ bool CActiveSocket::ConnectUDP(const char *pAddr, uint16 nPort) { - bool bRetVal = false; struct in_addr stIpAddress; //------------------------------------------------------------------ @@ -152,7 +151,7 @@ bool CActiveSocket::ConnectUDP(const char *pAddr, uint16 nPort) SetSocketError(SocketInvalidAddress); } #endif - return bRetVal; + return false; } memcpy(&stIpAddress, m_pHE->h_addr_list[0], m_pHE->h_length); @@ -161,7 +160,7 @@ bool CActiveSocket::ConnectUDP(const char *pAddr, uint16 nPort) if ((int32)m_stServerSockaddr.sin_addr.s_addr == CSimpleSocket::SocketError) { TranslateSocketError(); - return bRetVal; + return false; } m_stServerSockaddr.sin_port = htons(nPort); @@ -173,16 +172,15 @@ bool CActiveSocket::ConnectUDP(const char *pAddr, uint16 nPort) m_timer.Initialize(); m_timer.SetStartTime(); - if (connect(m_socket, (struct sockaddr*)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) != CSimpleSocket::SocketError) + if (connect(m_socket, (struct sockaddr*)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) == CSimpleSocket::SocketError) { - bRetVal = true; + TranslateSocketError(); + return false; } - TranslateSocketError(); - m_timer.SetEndTime(); - return bRetVal; + return true; } //------------------------------------------------------------------------------ @@ -192,7 +190,6 @@ bool CActiveSocket::ConnectUDP(const char *pAddr, uint16 nPort) //------------------------------------------------------------------------------ bool CActiveSocket::ConnectRAW(const char *pAddr, uint16 nPort) { - bool bRetVal = false; struct in_addr stIpAddress; //------------------------------------------------------------------ // Pre-connection setup that must be preformed @@ -210,7 +207,7 @@ bool CActiveSocket::ConnectRAW(const char *pAddr, uint16 nPort) SetSocketError(SocketInvalidAddress); } #endif - return bRetVal; + return false; } memcpy(&stIpAddress, m_pHE->h_addr_list[0], m_pHE->h_length); @@ -219,7 +216,7 @@ bool CActiveSocket::ConnectRAW(const char *pAddr, uint16 nPort) if ((int32)m_stServerSockaddr.sin_addr.s_addr == CSimpleSocket::SocketError) { TranslateSocketError(); - return bRetVal; + return false; } m_stServerSockaddr.sin_port = htons(nPort); @@ -231,16 +228,14 @@ bool CActiveSocket::ConnectRAW(const char *pAddr, uint16 nPort) m_timer.Initialize(); m_timer.SetStartTime(); - if (connect(m_socket, (struct sockaddr*)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) != CSimpleSocket::SocketError) + if (connect(m_socket, (struct sockaddr*)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) == CSimpleSocket::SocketError) { - bRetVal = true; + TranslateSocketError(); + return false; } - TranslateSocketError(); - m_timer.SetEndTime(); - - return bRetVal; + return true; } @@ -251,26 +246,25 @@ bool CActiveSocket::ConnectRAW(const char *pAddr, uint16 nPort) //------------------------------------------------------------------------------ bool CActiveSocket::Open(const char *pAddr, uint16 nPort) { - bool bRetVal = false; - if (IsSocketValid() == false) { SetSocketError(CSimpleSocket::SocketInvalidSocket); - return bRetVal; + return false; } if (pAddr == NULL) { SetSocketError(CSimpleSocket::SocketInvalidAddress); - return bRetVal; + return false; } if (nPort == 0) { SetSocketError(CSimpleSocket::SocketInvalidPort); - return bRetVal; + return false; } + bool bRetVal = false; switch (m_nSocketType) { case CSimpleSocket::SocketTypeTcp : diff --git a/src/Host.h b/src/Host.h index 91b3d16..c3fb101 100644 --- a/src/Host.h +++ b/src/Host.h @@ -156,13 +156,18 @@ extern "C" #define SHUT_RDWR 2 #define ACCEPT(a,b,c) accept(a,b,c) #define CONNECT(a,b,c) connect(a,b,c) +// returns -1 on error #define CLOSE(a) closesocket(a) #define READ(a,b,c) read(a,b,c) +// returns -1 on error #define RECV(a,b,c,d) recv(a, (char *)b, c, d) +// returns -1 on error #define RECVFROM(a,b,c,d,e,f) recvfrom(a, (char *)b, c, d, (sockaddr *)e, (int *)f) #define RECV_FLAGS MSG_WAITALL #define SELECT(a,b,c,d,e) select((int32)a,b,c,d,e) +// returns -1 on error #define SEND(a,b,c,d) send(a, (const char *)b, (int)c, d) +// returns -1 on error #define SENDTO(a,b,c,d,e,f) sendto(a, (const char *)b, (int)c, d, e, f) #define SEND_FLAGS 0 #define SENDFILE(a,b,c,d) sendfile(a, b, c, d) @@ -172,6 +177,7 @@ extern "C" #define WRITE(a,b,c) write(a,b,c) #define WRITEV(a,b,c) Writev(b, c) #define GETSOCKOPT(a,b,c,d,e) getsockopt(a,b,c,(char *)d, (int *)e) +// returns -1 on error #define SETSOCKOPT(a,b,c,d,e) setsockopt(a,b,c,(char *)d, (int)e) #define GETHOSTBYNAME(a) gethostbyname(a) #endif @@ -179,13 +185,18 @@ extern "C" #if defined(_LINUX) || defined(_DARWIN) #define ACCEPT(a,b,c) accept(a,b,c) #define CONNECT(a,b,c) connect(a,b,c) +// returns -1 on error #define CLOSE(a) close(a) #define READ(a,b,c) read(a,b,c) +// returns -1 on error #define RECV(a,b,c,d) recv(a, (void *)b, c, d) +// returns -1 on error #define RECVFROM(a,b,c,d,e,f) recvfrom(a, (char *)b, c, d, (sockaddr *)e, f) #define RECV_FLAGS MSG_WAITALL #define SELECT(a,b,c,d,e) select(a,b,c,d,e) +// returns -1 on error #define SEND(a,b,c,d) send(a, (const int8 *)b, c, d) +// returns -1 on error #define SENDTO(a,b,c,d,e,f) sendto(a, (const int8 *)b, c, d, e, f) #define SEND_FLAGS 0 #define SENDFILE(a,b,c,d) sendfile(a, b, c, d) @@ -195,6 +206,7 @@ extern "C" #define WRITE(a,b,c) write(a,b,c) #define WRITEV(a,b,c) writev(a, b, c) #define GETSOCKOPT(a,b,c,d,e) getsockopt((int)a,(int)b,(int)c,(void *)d,(socklen_t *)e) +// returns -1 on error #define SETSOCKOPT(a,b,c,d,e) setsockopt((int)a,(int)b,(int)c,(const void *)d,(int)e) #define GETHOSTBYNAME(a) gethostbyname(a) #endif diff --git a/src/PassiveSocket.cpp b/src/PassiveSocket.cpp index b9dce77..ffd649a 100644 --- a/src/PassiveSocket.cpp +++ b/src/PassiveSocket.cpp @@ -50,7 +50,6 @@ CPassiveSocket::CPassiveSocket(CSocketType nType) : CSimpleSocket(nType) bool CPassiveSocket::BindMulticast(const char *pInterface, const char *pGroup, uint16 nPort) { - bool bRetVal = false; #ifdef WIN32 ULONG inAddr; #else @@ -82,43 +81,32 @@ bool CPassiveSocket::BindMulticast(const char *pInterface, const char *pGroup, u } } - //-------------------------------------------------------------------------- - // Bind to the specified port - //-------------------------------------------------------------------------- - if (bind(m_socket, (struct sockaddr *)&m_stMulticastGroup, sizeof(m_stMulticastGroup)) == 0) + if (bind(m_socket, (struct sockaddr *)&m_stMulticastGroup, sizeof(m_stMulticastGroup)) == CSimpleSocket::SocketError) { - //---------------------------------------------------------------------- - // Join the multicast group - //---------------------------------------------------------------------- - m_stMulticastRequest.imr_multiaddr.s_addr = inet_addr(pGroup); - m_stMulticastRequest.imr_interface.s_addr = m_stMulticastGroup.sin_addr.s_addr; - - if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (void *)&m_stMulticastRequest, - sizeof(m_stMulticastRequest)) == CSimpleSocket::SocketSuccess) - { - bRetVal = true; - } - - m_timer.SetEndTime(); + TranslateSocketError(); + Close(); + return false; } - m_timer.Initialize(); - m_timer.SetStartTime(); - - - //-------------------------------------------------------------------------- - // If there was a socket error then close the socket to clean out the - // connection in the backlog. - //-------------------------------------------------------------------------- - TranslateSocketError(); + // Join the multicast group + m_stMulticastRequest.imr_multiaddr.s_addr = inet_addr(pGroup); + m_stMulticastRequest.imr_interface.s_addr = m_stMulticastGroup.sin_addr.s_addr; - if (bRetVal == false) + if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (void *)&m_stMulticastRequest, + sizeof(m_stMulticastRequest)) == CSimpleSocket::SocketError) { + + TranslateSocketError(); Close(); + return false; } - return bRetVal; + m_timer.SetEndTime(); + m_timer.Initialize(); + m_timer.SetStartTime(); + + return true; } @@ -129,7 +117,6 @@ bool CPassiveSocket::BindMulticast(const char *pInterface, const char *pGroup, u //------------------------------------------------------------------------------ bool CPassiveSocket::Listen(const char *pAddr, uint16 nPort, int32 nConnectionBacklog) { - bool bRetVal = false; #ifdef WIN32 ULONG inAddr; #else @@ -170,40 +157,25 @@ bool CPassiveSocket::Listen(const char *pAddr, uint16 nPort, int32 nConnectionBa m_timer.Initialize(); m_timer.SetStartTime(); - //-------------------------------------------------------------------------- - // Bind to the specified port - //-------------------------------------------------------------------------- - if (bind(m_socket, (struct sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) != CSimpleSocket::SocketError) + if (bind(m_socket, (struct sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) == CSimpleSocket::SocketError) { - if (m_nSocketType == CSimpleSocket::SocketTypeTcp) - { - if (listen(m_socket, nConnectionBacklog) != CSimpleSocket::SocketError) - { - bRetVal = true; - } - } - else - { - bRetVal = true; - } + TranslateSocketError(); + Close(); + return false; } - m_timer.SetEndTime(); - - //-------------------------------------------------------------------------- - // If there was a socket error then close the socket to clean out the - // connection in the backlog. - //-------------------------------------------------------------------------- - TranslateSocketError(); - - if (bRetVal == false) + if (m_nSocketType == CSimpleSocket::SocketTypeTcp) { - CSocketError err = GetSocketError(); - Close(); - SetSocketError(err); + if (listen(m_socket, nConnectionBacklog) == CSimpleSocket::SocketError) + { + TranslateSocketError(); + Close(); + return false; + } } - return bRetVal; + m_timer.SetEndTime(); + return true; } @@ -231,7 +203,7 @@ CActiveSocket *CPassiveSocket::Accept() //-------------------------------------------------------------------------- if (pClientSocket != NULL) { - CSocketError socketErrno = SocketSuccess; + CSocketError socketErrno = CSimpleSocket::SocketSuccess; m_timer.Initialize(); m_timer.SetStartTime(); @@ -240,32 +212,27 @@ CActiveSocket *CPassiveSocket::Accept() do { - errno = 0; + socketErrno = CSimpleSocket::SocketSuccess; socket = accept(m_socket, (struct sockaddr *)&m_stClientSockaddr, (socklen_t *)&nSockLen); - - if (socket != -1) - { - pClientSocket->SetSocketHandle(socket); - pClientSocket->TranslateSocketError(); - socketErrno = pClientSocket->GetSocketError(); - socklen_t nSockLen = sizeof(struct sockaddr); - - //------------------------------------------------------------- - // Store client and server IP and port information for this - // connection. - //------------------------------------------------------------- - getpeername(m_socket, (struct sockaddr *)&pClientSocket->m_stClientSockaddr, &nSockLen); - memcpy((void *)&pClientSocket->m_stClientSockaddr, (void *)&m_stClientSockaddr, nSockLen); - - memset(&pClientSocket->m_stServerSockaddr, 0, nSockLen); - getsockname(m_socket, (struct sockaddr *)&pClientSocket->m_stServerSockaddr, &nSockLen); - } - else - { + if (socket == INVALID_SOCKET) { TranslateSocketError(); socketErrno = GetSocketError(); + continue; } + pClientSocket->SetSocketHandle(socket); + pClientSocket->TranslateSocketError(); + socketErrno = pClientSocket->GetSocketError(); + socklen_t nSockLen = sizeof(struct sockaddr); + + // Store client and server IP and port information for this + // connection. + getpeername(m_socket, (struct sockaddr *)&pClientSocket->m_stClientSockaddr, &nSockLen); + memcpy((void *)&pClientSocket->m_stClientSockaddr, (void *)&m_stClientSockaddr, nSockLen); + + memset(&pClientSocket->m_stServerSockaddr, 0, nSockLen); + getsockname(m_socket, (struct sockaddr *)&pClientSocket->m_stServerSockaddr, &nSockLen); + } while (socketErrno == CSimpleSocket::SocketInterrupted); m_timer.SetEndTime(); @@ -288,7 +255,6 @@ CActiveSocket *CPassiveSocket::Accept() //------------------------------------------------------------------------------ int32 CPassiveSocket::Send(const uint8 *pBuf, size_t bytesToSend) { - SetSocketError(SocketSuccess); m_nBytesSent = 0; switch(m_nSocketType) @@ -307,22 +273,22 @@ int32 CPassiveSocket::Send(const uint8 *pBuf, size_t bytesToSend) sizeof(m_stClientSockaddr)); m_timer.SetEndTime(); - - if (m_nBytesSent == CSimpleSocket::SocketError) - { - TranslateSocketError(); - } } } break; } case CSimpleSocket::SocketTypeTcp: - CSimpleSocket::Send(pBuf, bytesToSend); + m_nBytesSent = CSimpleSocket::Send(pBuf, bytesToSend); break; default: SetSocketError(SocketProtocolError); break; } + if (m_nBytesSent == CSimpleSocket::SocketError) + { + TranslateSocketError(); + } + return m_nBytesSent; } diff --git a/src/SimpleSocket.cpp b/src/SimpleSocket.cpp index 3058e65..72056c9 100644 --- a/src/SimpleSocket.cpp +++ b/src/SimpleSocket.cpp @@ -41,6 +41,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. *----------------------------------------------------------------------------*/ #include "SimpleSocket.h" +#include CSimpleSocket::CSimpleSocket(CSocketType nType) : m_socket(INVALID_SOCKET), @@ -135,14 +136,18 @@ CSimpleSocket *CSimpleSocket::operator=(CSimpleSocket &socket) //------------------------------------------------------------------------------ bool CSimpleSocket::Initialize() { - errno = CSimpleSocket::SocketSuccess; + SetSocketError(CSimpleSocket::SocketSuccess); #ifdef WIN32 //------------------------------------------------------------------------- // Data structure containing general Windows Sockets Info //------------------------------------------------------------------------- memset(&m_hWSAData, 0, sizeof(m_hWSAData)); - WSAStartup(MAKEWORD(2, 0), &m_hWSAData); + auto starterr = WSAStartup(MAKEWORD(2, 0), &m_hWSAData); + if (starterr != 0) { + SetSocketError(starterr); + return false; + } #endif //------------------------------------------------------------------------- @@ -150,12 +155,15 @@ bool CSimpleSocket::Initialize() //------------------------------------------------------------------------- m_timer.Initialize(); m_timer.SetStartTime(); - m_socket = socket(m_nSocketDomain, m_nSocketType, 0); - m_timer.SetEndTime(); - TranslateSocketError(); + m_socket = socket(m_nSocketDomain, m_nSocketType, 0); + if (m_socket == INVALID_SOCKET) { + TranslateSocketError(); + return false; + } - return (IsSocketValid()); + m_timer.SetEndTime(); + return true; } @@ -166,26 +174,21 @@ bool CSimpleSocket::Initialize() //------------------------------------------------------------------------------ bool CSimpleSocket::BindInterface(const char *pInterface) { - bool bRetVal = false; struct in_addr stInterfaceAddr; - if (GetMulticast() == true) + if (GetMulticast() == true && pInterface) { - if (pInterface) + stInterfaceAddr.s_addr= inet_addr(pInterface); + if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_MULTICAST_IF, &stInterfaceAddr, sizeof(stInterfaceAddr)) == CSimpleSocket::SocketError) { - stInterfaceAddr.s_addr= inet_addr(pInterface); - if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_MULTICAST_IF, &stInterfaceAddr, sizeof(stInterfaceAddr)) == SocketSuccess) - { - bRetVal = true; - } + TranslateSocketError(); + return false; } - } - else - { - SetSocketError(CSimpleSocket::SocketProtocolError); + return true; } - return bRetVal; + SetSocketError(CSimpleSocket::SocketProtocolError); + return false; } @@ -196,27 +199,19 @@ bool CSimpleSocket::BindInterface(const char *pInterface) //------------------------------------------------------------------------------ bool CSimpleSocket::SetMulticast(bool bEnable, uint8 multicastTTL) { - bool bRetVal = false; - if (GetSocketType() == CSimpleSocket::SocketTypeUdp) { m_bIsMulticast = bEnable; - if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&multicastTTL, sizeof(multicastTTL)) == SocketError) + if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&multicastTTL, sizeof(multicastTTL)) == CSimpleSocket::SocketError) { TranslateSocketError(); - bRetVal = false; + return false; } - else - { - bRetVal = true; - } - } - else - { - m_socketErrno = CSimpleSocket::SocketProtocolError; + return true; } - return bRetVal; + SetSocketError(CSimpleSocket::SocketProtocolError); + return false; } @@ -227,22 +222,21 @@ bool CSimpleSocket::SetMulticast(bool bEnable, uint8 multicastTTL) //------------------------------------------------------------------------------ bool CSimpleSocket::SetSocketDscp(int32 nDscp) { - bool bRetVal = true; + if (!IsSocketValid()) + return false; + int32 nTempVal = nDscp; nTempVal <<= 4; nTempVal /= 4; - if (IsSocketValid()) + if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_TOS, &nTempVal, sizeof(nTempVal)) == CSimpleSocket::SocketError) { - if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_TOS, &nTempVal, sizeof(nTempVal)) == SocketError) - { - TranslateSocketError(); - bRetVal = false; - } + TranslateSocketError(); + return false; } - return bRetVal; + return true; } @@ -251,22 +245,22 @@ bool CSimpleSocket::SetSocketDscp(int32 nDscp) // GetSocketDscp() // //------------------------------------------------------------------------------ -int32 CSimpleSocket::GetSocketDscp(void) +int32 CSimpleSocket::GetSocketDscp() { + if (!IsSocketValid()) + return 0; + int32 nTempVal = 0; socklen_t nLen = 0; - - if (IsSocketValid()) + if (GETSOCKOPT(m_socket, IPPROTO_IP, IP_TOS, &nTempVal, &nLen) == CSimpleSocket::SocketError) { - if (GETSOCKOPT(m_socket, IPPROTO_IP, IP_TOS, &nTempVal, &nLen) == SocketError) - { - TranslateSocketError(); - } - - nTempVal *= 4; - nTempVal >>= 4; + TranslateSocketError(); + return 0; } + nTempVal *= 4; + nTempVal >>= 4; + return nTempVal; } @@ -278,24 +272,15 @@ int32 CSimpleSocket::GetSocketDscp(void) //------------------------------------------------------------------------------ uint32 CSimpleSocket::GetWindowSize(uint32 nOptionName) { - uint32 nTcpWinSize = 0; - - //------------------------------------------------------------------------- - // no socket given, return system default allocate our own new socket - //------------------------------------------------------------------------- - if (m_socket != CSimpleSocket::SocketError) - { - socklen_t nLen = sizeof(nTcpWinSize); + if (!IsSocketValid()) + return 0; - //--------------------------------------------------------------------- - // query for buffer size - //--------------------------------------------------------------------- - GETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nTcpWinSize, &nLen); + // query for buffer size + uint32 nTcpWinSize = 0; + socklen_t nLen = sizeof(nTcpWinSize); + if (GETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nTcpWinSize, &nLen) == CSimpleSocket::SocketError) { TranslateSocketError(); - } - else - { - SetSocketError(CSimpleSocket::SocketInvalidSocket); + return 0; } return nTcpWinSize; @@ -309,68 +294,37 @@ uint32 CSimpleSocket::GetWindowSize(uint32 nOptionName) //------------------------------------------------------------------------------ uint32 CSimpleSocket::SetWindowSize(uint32 nOptionName, uint32 nWindowSize) { - //------------------------------------------------------------------------- - // no socket given, return system default allocate our own new socket - //------------------------------------------------------------------------- - if (m_socket != CSimpleSocket::SocketError) - { - SETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nWindowSize, sizeof(nWindowSize)); + if (!IsSocketValid()) + return 0; + + if (SETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nWindowSize, sizeof(nWindowSize)) == CSimpleSocket::SocketError) { TranslateSocketError(); - } - else - { - SetSocketError(CSimpleSocket::SocketInvalidSocket); + return 0; } return nWindowSize; } - -//------------------------------------------------------------------------------ -// -// DisableNagleAlgorithm() -// -//------------------------------------------------------------------------------ -bool CSimpleSocket::DisableNagleAlgoritm() +bool CSimpleSocket::SetTcpNoDelay(bool enable) { - bool bRetVal = false; - int32 nTcpNoDelay = 1; + int32_t v = enable ? 1 : 0; - //---------------------------------------------------------------------- - // Set TCP NoDelay flag to true - //---------------------------------------------------------------------- - if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(int32)) == 0) + if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(int32_t)) == CSimpleSocket::SocketError) { - bRetVal = true; + CSimpleSocket::TranslateSocketError(); + return false; } - - TranslateSocketError(); - - return bRetVal; + return true; } +bool CSimpleSocket::DisableNagleAlgoritm() +{ + return SetTcpNoDelay(true); +} -//------------------------------------------------------------------------------ -// -// EnableNagleAlgorithm() -// -//------------------------------------------------------------------------------ bool CSimpleSocket::EnableNagleAlgoritm() { - bool bRetVal = false; - int32 nTcpNoDelay = 0; - - //---------------------------------------------------------------------- - // Set TCP NoDelay flag to false - //---------------------------------------------------------------------- - if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(int32)) == 0) - { - bRetVal = true; - } - - TranslateSocketError(); - - return bRetVal; + return SetTcpNoDelay(false); } @@ -381,43 +335,43 @@ bool CSimpleSocket::EnableNagleAlgoritm() //------------------------------------------------------------------------------ int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) { - SetSocketError(SocketSuccess); + if (!IsSocketValid()) + return 0; + + SetSocketError(CSimpleSocket::SocketSuccess); m_nBytesSent = 0; switch(m_nSocketType) { case CSimpleSocket::SocketTypeTcp: { - if (IsSocketValid()) + if ((bytesToSend > 0) && (pBuf != NULL)) { - if ((bytesToSend > 0) && (pBuf != NULL)) - { - m_timer.Initialize(); - m_timer.SetStartTime(); + m_timer.Initialize(); + m_timer.SetStartTime(); - //--------------------------------------------------------- - // Check error condition and attempt to resend if call - // was interrupted by a signal. - //--------------------------------------------------------- - do - { - m_nBytesSent = SEND(m_socket, pBuf, bytesToSend, 0); - TranslateSocketError(); - } while (GetSocketError() == CSimpleSocket::SocketInterrupted); + //--------------------------------------------------------- + // Check error condition and attempt to resend if call + // was interrupted by a signal. + //--------------------------------------------------------- + do + { + m_nBytesSent = SEND(m_socket, pBuf, bytesToSend, 0); + if (m_nBytesSent != CSimpleSocket::SocketError) + break; + TranslateSocketError(); + } while (GetSocketError() == CSimpleSocket::SocketInterrupted); - m_timer.SetEndTime(); - } + m_timer.SetEndTime(); } break; } case CSimpleSocket::SocketTypeUdp: { - if (IsSocketValid()) + if ((bytesToSend > 0) && (pBuf != NULL)) { - if ((bytesToSend > 0) && (pBuf != NULL)) - { - m_timer.Initialize(); - m_timer.SetStartTime(); + m_timer.Initialize(); + m_timer.SetStartTime(); //--------------------------------------------------------- // Check error condition and attempt to resend if call @@ -433,16 +387,17 @@ int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) // } while (GetSocketError() == CSimpleSocket::SocketInterrupted); // } // else + { + do { - do - { - m_nBytesSent = SENDTO(m_socket, pBuf, bytesToSend, 0, (const sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)); - TranslateSocketError(); - } while (GetSocketError() == CSimpleSocket::SocketInterrupted); - } - - m_timer.SetEndTime(); + m_nBytesSent = SENDTO(m_socket, pBuf, bytesToSend, 0, (const sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)); + if (m_nBytesSent != CSimpleSocket::SocketError) + break; + TranslateSocketError(); + } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } + + m_timer.SetEndTime(); } break; } @@ -459,10 +414,8 @@ int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) // Close() - Close socket and free up any memory allocated for the socket // //------------------------------------------------------------------------------ -bool CSimpleSocket::Close(void) +bool CSimpleSocket::Close() { - bool bRetVal = false; - //-------------------------------------------------------------------------- // delete internal buffer //-------------------------------------------------------------------------- @@ -472,21 +425,19 @@ bool CSimpleSocket::Close(void) m_pBuffer = NULL; } - //-------------------------------------------------------------------------- - // if socket handle is currently valid, close and then invalidate - //-------------------------------------------------------------------------- - if (IsSocketValid()) + if (!IsSocketValid()) { - if (CLOSE(m_socket) != CSimpleSocket::SocketError) - { - m_socket = INVALID_SOCKET; - bRetVal = true; - } + return false; } - TranslateSocketError(); - - return bRetVal; + if (CLOSE(m_socket) == CSimpleSocket::SocketError) + { + TranslateSocketError(); + return false; + } + // XXX: FIXME: always mark invalid socket? the buffer was deleted. + m_socket = INVALID_SOCKET; + return true; } @@ -497,12 +448,12 @@ bool CSimpleSocket::Close(void) //------------------------------------------------------------------------------ bool CSimpleSocket::Shutdown(CShutdownMode nShutdown) { - CSocketError nRetVal = SocketEunknown; - - nRetVal = (CSocketError)shutdown(m_socket, nShutdown); - TranslateSocketError(); + if (shutdown(m_socket, nShutdown) == CSimpleSocket::SocketError) { + TranslateSocketError(); + return false; + } - return (nRetVal == CSimpleSocket::SocketSuccess) ? true: false; + return true; } @@ -515,37 +466,30 @@ bool CSimpleSocket::Flush() { int32 nTcpNoDelay = 1; int32 nCurFlags = 0; - uint8 tmpbuf = 0; - bool bRetVal = false; + bool ret = true; - //-------------------------------------------------------------------------- - // Get the current setting of the TCP_NODELAY flag. - //-------------------------------------------------------------------------- - if (GETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)) == 0) - { - //---------------------------------------------------------------------- - // Set TCP NoDelay flag - //---------------------------------------------------------------------- - if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(int32)) == 0) - { - //------------------------------------------------------------------ - // Send empty byte stream to flush the TCP send buffer - //------------------------------------------------------------------ - if (Send(&tmpbuf, 0) != CSimpleSocket::SocketError) - { - bRetVal = true; - } + try { + if (GETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)) == CSocketError::SocketError) + throw(std::runtime_error("Failed to retrieve TCP_NODELAY setting")); - TranslateSocketError(); - } + if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(int32)) == CSocketError::SocketError) + throw(std::runtime_error("Failed to set TCP_NODELAY option")); - //---------------------------------------------------------------------- - // Reset the TCP_NODELAY flag to original state. - //---------------------------------------------------------------------- - SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)); + // Send empty byte stream to flush the TCP send buffer + uint8 tmpbuf = 0; + if (Send(&tmpbuf, 0) == CSocketError::SocketError) + throw(std::runtime_error("Failed to send")); + + } catch (std::runtime_error& e) { + TranslateSocketError(); + ret = false; + + if (nCurFlags != nTcpNoDelay) { + SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)); + } } - return bRetVal; + return ret; } @@ -558,13 +502,13 @@ int32 CSimpleSocket::Writev(const struct iovec *pVector, size_t nCount) { int32 nBytes = 0; int32 nBytesSent = 0; - int32 i = 0; + size_t i = 0; //-------------------------------------------------------------------------- // Send each buffer as a separate send, windows does not support this // function call. //-------------------------------------------------------------------------- - for (i = 0; i < (int32)nCount; i++) + for (i = 0; i < nCount; i++) { if ((nBytes = Send((uint8 *)pVector[i].iov_base, pVector[i].iov_len)) == CSimpleSocket::SocketError) { @@ -590,7 +534,6 @@ int32 CSimpleSocket::Writev(const struct iovec *pVector, size_t nCount) //------------------------------------------------------------------------------ int32 CSimpleSocket::Send(const struct iovec *sendVector, int32 nNumItems) { - SetSocketError(SocketSuccess); m_nBytesSent = 0; if ((m_nBytesSent = WRITEV(m_socket, sendVector, nNumItems)) == CSimpleSocket::SocketError) @@ -609,8 +552,6 @@ int32 CSimpleSocket::Send(const struct iovec *sendVector, int32 nNumItems) //------------------------------------------------------------------------------ bool CSimpleSocket::SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutUsec) { - bool bRetVal = true; - memset(&m_stRecvTimeout, 0, sizeof(struct timeval)); m_stRecvTimeout.tv_sec = nRecvTimeoutSec; @@ -622,11 +563,11 @@ bool CSimpleSocket::SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutU if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_RCVTIMEO, &m_stRecvTimeout, sizeof(struct timeval)) == CSimpleSocket::SocketError) { - bRetVal = false; TranslateSocketError(); + return false; } - return bRetVal; + return true; } @@ -637,8 +578,6 @@ bool CSimpleSocket::SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutU //------------------------------------------------------------------------------ bool CSimpleSocket::SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec) { - bool bRetVal = true; - memset(&m_stSendTimeout, 0, sizeof(struct timeval)); m_stSendTimeout.tv_sec = nSendTimeoutSec; m_stSendTimeout.tv_usec = nSendTimeoutUsec; @@ -649,11 +588,11 @@ bool CSimpleSocket::SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_SNDTIMEO, &m_stSendTimeout, sizeof(struct timeval)) == CSimpleSocket::SocketError) { - bRetVal = false; TranslateSocketError(); + return false; } - return bRetVal; + return true; } @@ -664,17 +603,15 @@ bool CSimpleSocket::SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec //------------------------------------------------------------------------------ bool CSimpleSocket::SetOptionReuseAddr() { - bool bRetVal = false; int32 nReuse = IPTOS_LOWDELAY; - if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&nReuse, sizeof(int32)) == 0) + if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&nReuse, sizeof(int32)) == CSimpleSocket::SocketError) { - bRetVal = true; + TranslateSocketError(); + return false; } - TranslateSocketError(); - - return bRetVal; + return true; } @@ -685,19 +622,16 @@ bool CSimpleSocket::SetOptionReuseAddr() //------------------------------------------------------------------------------ bool CSimpleSocket::SetOptionLinger(bool bEnable, uint16 nTime) { - bool bRetVal = false; - - m_stLinger.l_onoff = (bEnable == true) ? 1: 0; + m_stLinger.l_onoff = int(bEnable); m_stLinger.l_linger = nTime; - if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_LINGER, &m_stLinger, sizeof(m_stLinger)) == 0) + if (SETSOCKOPT(m_socket, SOL_SOCKET, SO_LINGER, &m_stLinger, sizeof(m_stLinger)) == CSimpleSocket::SocketError) { - bRetVal = true; + TranslateSocketError(); + return false; } - TranslateSocketError(); - - return bRetVal; + return true; } @@ -719,7 +653,7 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) //-------------------------------------------------------------------------- if (IsSocketValid() == false) { - return m_nBytesReceived; + return 0; } uint8 * pWorkBuffer = pBuffer; @@ -764,6 +698,8 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) { m_nBytesReceived = RECV(m_socket, (pWorkBuffer + m_nBytesReceived), nMaxBytes, m_nFlags); + if (m_nBytesReceived != CSimpleSocket::SocketError) + break; TranslateSocketError(); } while ((GetSocketError() == CSimpleSocket::SocketInterrupted)); @@ -781,6 +717,8 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) { m_nBytesReceived = RECVFROM(m_socket, pWorkBuffer, nMaxBytes, 0, &m_stMulticastGroup, &srcSize); + if (m_nBytesReceived != CSocketError::SocketError) + break; TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } @@ -790,6 +728,8 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) { m_nBytesReceived = RECVFROM(m_socket, pWorkBuffer, nMaxBytes, 0, &m_stClientSockaddr, &srcSize); + if (m_nBytesReceived != CSimpleSocket::SocketError) + break; TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } @@ -801,7 +741,6 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) } m_timer.SetEndTime(); - TranslateSocketError(); //-------------------------------------------------------------------------- // If we encounter an error translate the error code and return. One @@ -856,7 +795,6 @@ bool CSimpleSocket::SetNonblocking(void) #endif m_bIsBlocking = false; - return true; } @@ -875,6 +813,7 @@ bool CSimpleSocket::SetBlocking(void) if (ioctlsocket(m_socket, FIONBIO, (ULONG *)&nCurFlags) != 0) { + TranslateSocketError(); return false; } #else @@ -919,12 +858,12 @@ int32 CSimpleSocket::SendFile(int32 nOutFd, int32 nInFd, off_t *pOffset, int32 n { nInCount = (nCount - nOutCount) < SOCKET_SENDFILE_BLOCKSIZE ? (nCount - nOutCount) : SOCKET_SENDFILE_BLOCKSIZE; - if ((read(nInFd, szData, nInCount)) != (int32)nInCount) + if ((read(nInFd, szData, nInCount)) != nInCount) { return -1; } - if ((SEND(nOutFd, szData, nInCount, 0)) != (int32)nInCount) + if ((SEND(nOutFd, szData, nInCount, 0)) != nInCount) { return -1; } @@ -934,12 +873,9 @@ int32 CSimpleSocket::SendFile(int32 nOutFd, int32 nInFd, off_t *pOffset, int32 n *pOffset += nOutCount; - TranslateSocketError(); - return nOutCount; } - //------------------------------------------------------------------------------ // // TranslateSocketError() - @@ -950,7 +886,7 @@ void CSimpleSocket::TranslateSocketError(void) #if defined(_LINUX) || defined(_DARWIN) switch (errno) { - case EXIT_SUCCESS: + case 0: SetSocketError(CSimpleSocket::SocketSuccess); break; case ENOTCONN: @@ -1014,7 +950,7 @@ void CSimpleSocket::TranslateSocketError(void) int32 nError = WSAGetLastError(); switch (nError) { - case EXIT_SUCCESS: + case 0: SetSocketError(CSimpleSocket::SocketSuccess); break; case WSAEBADF: @@ -1128,7 +1064,6 @@ const char *CSimpleSocket::DescribeError(CSocketError err) //------------------------------------------------------------------------------ bool CSimpleSocket::Select(int32 nTimeoutSec, int32 nTimeoutUSec) { - bool bRetVal = false; struct timeval *pTimeout = NULL; struct timeval timeout; int32 nNumDescriptors = -1; @@ -1156,34 +1091,40 @@ bool CSimpleSocket::Select(int32 nTimeoutSec, int32 nTimeoutUSec) nNumDescriptors = SELECT(m_socket+1, &m_readFds, &m_writeFds, &m_errorFds, pTimeout); // nNumDescriptors = SELECT(m_socket+1, &m_readFds, NULL, NULL, pTimeout); + if (nNumDescriptors == CSimpleSocket::SocketError) { + TranslateSocketError(); + return false; + } + //---------------------------------------------------------------------- // Handle timeout //---------------------------------------------------------------------- if (nNumDescriptors == 0) { SetSocketError(CSimpleSocket::SocketTimedout); + return false; } //---------------------------------------------------------------------- // If a file descriptor (read/write) is set then check the // socket error (SO_ERROR) to see if there is a pending error. //---------------------------------------------------------------------- - else if ((FD_ISSET(m_socket, &m_readFds)) || (FD_ISSET(m_socket, &m_writeFds))) + if ((FD_ISSET(m_socket, &m_readFds)) || (FD_ISSET(m_socket, &m_writeFds))) { int32 nLen = sizeof(nError); if (GETSOCKOPT(m_socket, SOL_SOCKET, SO_ERROR, &nError, &nLen) == 0) { - errno = nError; - - if (nError == 0) - { - bRetVal = true; + if (nError != 0) { + SetSocketError(CSocketError(nError)); + TranslateSocketError(); + return false; } + } else { // getsockopt failed + TranslateSocketError(); + return false; } - - TranslateSocketError(); } - return bRetVal; + return true; } diff --git a/src/SimpleSocket.h b/src/SimpleSocket.h index f17af97..1b43092 100644 --- a/src/SimpleSocket.h +++ b/src/SimpleSocket.h @@ -87,8 +87,11 @@ //----------------------------------------------------------------------------- // General class macro definitions and typedefs //----------------------------------------------------------------------------- -#ifndef INVALID_SOCKET -#define INVALID_SOCKET ~(0) + +// Windows socket headers define INVALID_SOCKET +// For POSIX, it's -1. +#ifndef _WIN32 + #define INVALID_SOCKET -1 #endif #define SOCKET_SENDFILE_BLOCKSIZE 8192 @@ -141,6 +144,13 @@ class EXPORT CSimpleSocket { SocketConnectionReset, ///< Connection was forcibly closed by the remote host. SocketAddressInUse, ///< Address already in use. SocketInvalidPointer, ///< Pointer type supplied as argument is invalid. +#if _WIN32 + SocketWSASYSNOTREADY, + SocketWSAVERNOTSUPPORTED, + SocketWSAEINPROGRESS, + SocketWSAEPROCLIM, + SocketWSAEFAULT, +#endif SocketEunknown ///< Unknown error please report to mark@carrierlabs.com } CSocketError; @@ -550,6 +560,8 @@ class EXPORT CSimpleSocket { /// @return true data was successfully sent, else return false; bool Flush(); + bool SetTcpNoDelay(bool enable); + CSimpleSocket *operator=(CSimpleSocket &socket); protected: From 4a65d10a516c60fcc94ae9f8d9cee5efeb893227 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 22 Nov 2025 04:41:05 -0500 Subject: [PATCH 2/6] tweaks from last commit --- src/SimpleSocket.cpp | 13 +++++++++---- src/SimpleSocket.h | 9 +-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/SimpleSocket.cpp b/src/SimpleSocket.cpp index 72056c9..496a683 100644 --- a/src/SimpleSocket.cpp +++ b/src/SimpleSocket.cpp @@ -145,7 +145,7 @@ bool CSimpleSocket::Initialize() memset(&m_hWSAData, 0, sizeof(m_hWSAData)); auto starterr = WSAStartup(MAKEWORD(2, 0), &m_hWSAData); if (starterr != 0) { - SetSocketError(starterr); + SetSocketError(CSimpleSocket::SocketInvalidSocket); return false; } #endif @@ -311,7 +311,7 @@ bool CSimpleSocket::SetTcpNoDelay(bool enable) if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(int32_t)) == CSimpleSocket::SocketError) { - CSimpleSocket::TranslateSocketError(); + TranslateSocketError(); return false; } return true; @@ -357,7 +357,7 @@ int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) do { m_nBytesSent = SEND(m_socket, pBuf, bytesToSend, 0); - if (m_nBytesSent != CSimpleSocket::SocketError) + if (m_nBytesSent >= 0) break; TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); @@ -391,8 +391,9 @@ int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) do { m_nBytesSent = SENDTO(m_socket, pBuf, bytesToSend, 0, (const sockaddr *)&m_stServerSockaddr, sizeof(m_stServerSockaddr)); - if (m_nBytesSent != CSimpleSocket::SocketError) + if (m_nBytesSent >= 0) break; + TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); } @@ -757,6 +758,10 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) } } + // Peer closed the connection + if (m_nBytesReceived == 0) + Close(); + return m_nBytesReceived; } diff --git a/src/SimpleSocket.h b/src/SimpleSocket.h index 1b43092..db9d889 100644 --- a/src/SimpleSocket.h +++ b/src/SimpleSocket.h @@ -144,13 +144,6 @@ class EXPORT CSimpleSocket { SocketConnectionReset, ///< Connection was forcibly closed by the remote host. SocketAddressInUse, ///< Address already in use. SocketInvalidPointer, ///< Pointer type supplied as argument is invalid. -#if _WIN32 - SocketWSASYSNOTREADY, - SocketWSAVERNOTSUPPORTED, - SocketWSAEINPROGRESS, - SocketWSAEPROCLIM, - SocketWSAEFAULT, -#endif SocketEunknown ///< Unknown error please report to mark@carrierlabs.com } CSocketError; @@ -208,7 +201,7 @@ class EXPORT CSimpleSocket { /// descriptor. /// @return true if the socket object contains a valid socket descriptor. virtual bool IsSocketValid(void) { - return (m_socket != SocketError); + return (m_socket != INVALID_SOCKET); }; /// Provides a standard error code for cross platform development by From c5fc4bb756c8f3d1a70b76774271bef0db8de005 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 22 Nov 2025 05:42:44 -0500 Subject: [PATCH 3/6] A little cleanup for Accept() weirdness --- src/PassiveSocket.cpp | 47 +++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/PassiveSocket.cpp b/src/PassiveSocket.cpp index ffd649a..8f6d69f 100644 --- a/src/PassiveSocket.cpp +++ b/src/PassiveSocket.cpp @@ -186,34 +186,28 @@ bool CPassiveSocket::Listen(const char *pAddr, uint16 nPort, int32 nConnectionBa //------------------------------------------------------------------------------ CActiveSocket *CPassiveSocket::Accept() { - uint32 nSockLen; - CActiveSocket *pClientSocket = NULL; - SOCKET socket = CSimpleSocket::SocketError; - if (m_nSocketType != CSimpleSocket::SocketTypeTcp) { SetSocketError(CSimpleSocket::SocketProtocolError); - return pClientSocket; + return nullptr; } - pClientSocket = new CActiveSocket(); + auto pClientSocket = new CActiveSocket(); //-------------------------------------------------------------------------- // Wait for incoming connection. //-------------------------------------------------------------------------- - if (pClientSocket != NULL) - { - CSocketError socketErrno = CSimpleSocket::SocketSuccess; - + if (pClientSocket != nullptr) { + CSocketError socketErrno = CSimpleSocket::SocketError; m_timer.Initialize(); m_timer.SetStartTime(); - nSockLen = sizeof(m_stClientSockaddr); - - do - { + do { socketErrno = CSimpleSocket::SocketSuccess; - socket = accept(m_socket, (struct sockaddr *)&m_stClientSockaddr, (socklen_t *)&nSockLen); + uint32 nSockLen = sizeof(m_stClientSockaddr); + + SOCKET socket = accept(m_socket, (struct sockaddr *)&m_stClientSockaddr, (socklen_t *)&nSockLen); + if (socket == INVALID_SOCKET) { TranslateSocketError(); socketErrno = GetSocketError(); @@ -221,26 +215,21 @@ CActiveSocket *CPassiveSocket::Accept() } pClientSocket->SetSocketHandle(socket); - pClientSocket->TranslateSocketError(); - socketErrno = pClientSocket->GetSocketError(); - socklen_t nSockLen = sizeof(struct sockaddr); - - // Store client and server IP and port information for this - // connection. - getpeername(m_socket, (struct sockaddr *)&pClientSocket->m_stClientSockaddr, &nSockLen); - memcpy((void *)&pClientSocket->m_stClientSockaddr, (void *)&m_stClientSockaddr, nSockLen); - - memset(&pClientSocket->m_stServerSockaddr, 0, nSockLen); - getsockname(m_socket, (struct sockaddr *)&pClientSocket->m_stServerSockaddr, &nSockLen); + pClientSocket->m_stClientSockaddr = m_stClientSockaddr; + socklen_t sslen = sizeof(pClientSocket->m_stServerSockaddr); + if (getsockname(socket, (struct sockaddr *)&pClientSocket->m_stServerSockaddr, &sslen) == -1) { + TranslateSocketError(); + socketErrno = GetSocketError(); + break; + } } while (socketErrno == CSimpleSocket::SocketInterrupted); m_timer.SetEndTime(); - if (socketErrno != CSimpleSocket::SocketSuccess) - { + if (socketErrno != CSimpleSocket::SocketSuccess) { delete pClientSocket; - pClientSocket = NULL; + pClientSocket = nullptr; } } From 8a274e356a5c880ec4a3ad01622b6f0610b4168a Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 23 Nov 2025 11:56:44 -0500 Subject: [PATCH 4/6] Some fixes. Always invalidate socket handle on Close(). Make TCP Flush() NOOP as TCP itself doesnt support it. --- src/PassiveSocket.cpp | 1 + src/SimpleSocket.cpp | 53 +++++++++++-------------------------------- src/SimpleSocket.h | 8 ++++--- 3 files changed, 19 insertions(+), 43 deletions(-) diff --git a/src/PassiveSocket.cpp b/src/PassiveSocket.cpp index 8f6d69f..69d5858 100644 --- a/src/PassiveSocket.cpp +++ b/src/PassiveSocket.cpp @@ -267,6 +267,7 @@ int32 CPassiveSocket::Send(const uint8 *pBuf, size_t bytesToSend) break; } case CSimpleSocket::SocketTypeTcp: + // This function is for UDP. Shouldn't even get here. m_nBytesSent = CSimpleSocket::Send(pBuf, bytesToSend); break; default: diff --git a/src/SimpleSocket.cpp b/src/SimpleSocket.cpp index 496a683..808337d 100644 --- a/src/SimpleSocket.cpp +++ b/src/SimpleSocket.cpp @@ -41,7 +41,6 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. *----------------------------------------------------------------------------*/ #include "SimpleSocket.h" -#include CSimpleSocket::CSimpleSocket(CSocketType nType) : m_socket(INVALID_SOCKET), @@ -176,7 +175,7 @@ bool CSimpleSocket::BindInterface(const char *pInterface) { struct in_addr stInterfaceAddr; - if (GetMulticast() == true && pInterface) + if (GetMulticast() && pInterface) { stInterfaceAddr.s_addr= inet_addr(pInterface); if (SETSOCKOPT(m_socket, IPPROTO_IP, IP_MULTICAST_IF, &stInterfaceAddr, sizeof(stInterfaceAddr)) == CSimpleSocket::SocketError) @@ -278,7 +277,8 @@ uint32 CSimpleSocket::GetWindowSize(uint32 nOptionName) // query for buffer size uint32 nTcpWinSize = 0; socklen_t nLen = sizeof(nTcpWinSize); - if (GETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nTcpWinSize, &nLen) == CSimpleSocket::SocketError) { + if (GETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nTcpWinSize, &nLen) == CSimpleSocket::SocketError) + { TranslateSocketError(); return 0; } @@ -297,7 +297,8 @@ uint32 CSimpleSocket::SetWindowSize(uint32 nOptionName, uint32 nWindowSize) if (!IsSocketValid()) return 0; - if (SETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nWindowSize, sizeof(nWindowSize)) == CSimpleSocket::SocketError) { + if (SETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nWindowSize, sizeof(nWindowSize)) == CSimpleSocket::SocketError) + { TranslateSocketError(); return 0; } @@ -336,7 +337,7 @@ bool CSimpleSocket::EnableNagleAlgoritm() int32 CSimpleSocket::Send(const uint8 *pBuf, size_t bytesToSend) { if (!IsSocketValid()) - return 0; + return CSimpleSocket::SocketError; SetSocketError(CSimpleSocket::SocketSuccess); m_nBytesSent = 0; @@ -431,13 +432,14 @@ bool CSimpleSocket::Close() return false; } + m_socket = INVALID_SOCKET; + if (CLOSE(m_socket) == CSimpleSocket::SocketError) { TranslateSocketError(); return false; } - // XXX: FIXME: always mark invalid socket? the buffer was deleted. - m_socket = INVALID_SOCKET; + return true; } @@ -465,32 +467,8 @@ bool CSimpleSocket::Shutdown(CShutdownMode nShutdown) //------------------------------------------------------------------------------ bool CSimpleSocket::Flush() { - int32 nTcpNoDelay = 1; - int32 nCurFlags = 0; - bool ret = true; - - try { - if (GETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)) == CSocketError::SocketError) - throw(std::runtime_error("Failed to retrieve TCP_NODELAY setting")); - - if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(int32)) == CSocketError::SocketError) - throw(std::runtime_error("Failed to set TCP_NODELAY option")); - - // Send empty byte stream to flush the TCP send buffer - uint8 tmpbuf = 0; - if (Send(&tmpbuf, 0) == CSocketError::SocketError) - throw(std::runtime_error("Failed to send")); - - } catch (std::runtime_error& e) { - TranslateSocketError(); - ret = false; - - if (nCurFlags != nTcpNoDelay) { - SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(int32)); - } - } - - return ret; + // Can't flush a TCP socket. + return true; } @@ -519,11 +497,6 @@ int32 CSimpleSocket::Writev(const struct iovec *pVector, size_t nCount) nBytesSent += nBytes; } - if (i > 0) - { - Flush(); - } - return nBytesSent; } @@ -1093,6 +1066,7 @@ bool CSimpleSocket::Select(int32 nTimeoutSec, int32 nTimeoutUSec) pTimeout = &timeout; } + // On Windows the first argument is ignored. nNumDescriptors = SELECT(m_socket+1, &m_readFds, &m_writeFds, &m_errorFds, pTimeout); // nNumDescriptors = SELECT(m_socket+1, &m_readFds, NULL, NULL, pTimeout); @@ -1131,5 +1105,4 @@ bool CSimpleSocket::Select(int32 nTimeoutSec, int32 nTimeoutUSec) } return true; -} - +} \ No newline at end of file diff --git a/src/SimpleSocket.h b/src/SimpleSocket.h index db9d889..f7643bc 100644 --- a/src/SimpleSocket.h +++ b/src/SimpleSocket.h @@ -166,8 +166,10 @@ class EXPORT CSimpleSocket { /// @return true if properly initialized. virtual bool Initialize(void); - /// Close socket - /// @return true if successfully closed otherwise returns false. + /// Close socket. + /// The socket is marked unusable immediately regardless of return value, + /// @return true if the OS successfully closed + /// otherwise returns false if the OS encountered an error during cleanup. virtual bool Close(void); /// Shutdown shut down socket send and receive operations @@ -551,7 +553,7 @@ class EXPORT CSimpleSocket { /// Flush the socket descriptor owned by the object. /// @return true data was successfully sent, else return false; - bool Flush(); + static bool Flush(); bool SetTcpNoDelay(bool enable); From 63d8053eb7166102337daf13902176e1ddf07e75 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 23 Nov 2025 12:14:03 -0500 Subject: [PATCH 5/6] Some more error handling. Fix bug: use sizeof on the correct struct. --- src/ActiveSocket.cpp | 22 +++++++++++++++++----- src/SimpleSocket.cpp | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ActiveSocket.cpp b/src/ActiveSocket.cpp index a1ef62b..76b2543 100644 --- a/src/ActiveSocket.cpp +++ b/src/ActiveSocket.cpp @@ -288,16 +288,28 @@ bool CActiveSocket::Open(const char *pAddr, uint16 nPort) //-------------------------------------------------------------------------- if (bRetVal) { - socklen_t nSockLen = sizeof(struct sockaddr); + socklen_t nSockLen = sizeof(m_stServerSockaddr); memset(&m_stServerSockaddr, 0, nSockLen); - getpeername(m_socket, (struct sockaddr *)&m_stServerSockaddr, &nSockLen); + if (getpeername(m_socket, + (struct sockaddr *)&m_stServerSockaddr, + &nSockLen) == CSimpleSocket::SocketError) + { + TranslateSocketError(); + return false; + } - nSockLen = sizeof(struct sockaddr); + nSockLen = sizeof(m_stClientSockaddr); memset(&m_stClientSockaddr, 0, nSockLen); - getsockname(m_socket, (struct sockaddr *)&m_stClientSockaddr, &nSockLen); + if (getsockname(m_socket, + (struct sockaddr *)&m_stClientSockaddr, + &nSockLen) == CSimpleSocket::SocketError) + { + TranslateSocketError(); + return false; + } - SetSocketError(SocketSuccess); + SetSocketError(CSimpleSocket::SocketSuccess); } return bRetVal; diff --git a/src/SimpleSocket.cpp b/src/SimpleSocket.cpp index 808337d..b65cfe1 100644 --- a/src/SimpleSocket.cpp +++ b/src/SimpleSocket.cpp @@ -691,7 +691,7 @@ int32 CSimpleSocket::Receive(int32 nMaxBytes, uint8 * pBuffer ) { m_nBytesReceived = RECVFROM(m_socket, pWorkBuffer, nMaxBytes, 0, &m_stMulticastGroup, &srcSize); - if (m_nBytesReceived != CSocketError::SocketError) + if (m_nBytesReceived != CSimpleSocket::SocketError) break; TranslateSocketError(); } while (GetSocketError() == CSimpleSocket::SocketInterrupted); From 4a97b4e5fc28ee5e8e17ea19a812f1d878ac20ed Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 23 Nov 2025 14:26:55 -0500 Subject: [PATCH 6/6] fix windows compile --- src/SimpleSocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SimpleSocket.cpp b/src/SimpleSocket.cpp index b65cfe1..154c9b4 100644 --- a/src/SimpleSocket.cpp +++ b/src/SimpleSocket.cpp @@ -308,9 +308,9 @@ uint32 CSimpleSocket::SetWindowSize(uint32 nOptionName, uint32 nWindowSize) bool CSimpleSocket::SetTcpNoDelay(bool enable) { - int32_t v = enable ? 1 : 0; + int32 v = enable ? 1 : 0; - if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(int32_t)) == CSimpleSocket::SocketError) + if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(int32)) == CSimpleSocket::SocketError) { TranslateSocketError(); return false;