From 7e7dca8e27f57aa042028ae4d76a80465c8791cb Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Sun, 24 May 2015 20:25:49 -0400 Subject: [PATCH] Improved old code in connect() and bind(). --- Jupiter/Socket.cpp | 84 ++++++++++++++++++++++---------------------- Release/Jupiter.lib | Bin 267778 -> 267778 bytes 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Jupiter/Socket.cpp b/Jupiter/Socket.cpp index ad63250..aefdd9d 100644 --- a/Jupiter/Socket.cpp +++ b/Jupiter/Socket.cpp @@ -161,33 +161,35 @@ bool Jupiter::Socket::connect(addrinfo *info) bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) { #if defined _WIN32 - if (!socketInit && !Jupiter::Socket::init()) return false; + if (!socketInit && !Jupiter::Socket::init()) + return false; #endif // _WIN32 Jupiter::Socket::data_->host.set(hostname); Jupiter::Socket::data_->port = iPort; - int i = 0; - static char portString[256]; - sprintf(portString, "%hu", Jupiter::Socket::data_->port); - addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), portString); - while (info != nullptr) + addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->port).c_str()); + if (info_head != nullptr) { - addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i); - if (ainfo == nullptr) + addrinfo *info = info_head; + do { - Jupiter::Socket::freeAddrInfo(info); - return false; - } - sockaddr *asock = ainfo->ai_addr; - Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); - if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) continue; - if (clientAddress != nullptr) this->bind(clientAddress, clientPort, false); - if (::connect(Jupiter::Socket::data_->rawSock, asock, ainfo->ai_addrlen) == SOCKET_ERROR) - { - i++; - continue; - } - Jupiter::Socket::freeAddrInfo(info); - return true; + Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); + if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET) + { + info = info->ai_next; + continue; + } + + if (clientAddress != nullptr) + this->bind(clientAddress, clientPort, false); + if (::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) + { + info = info->ai_next; + continue; + } + Jupiter::Socket::freeAddrInfo(info_head); + return true; + } while (info != nullptr); + Jupiter::Socket::freeAddrInfo(info_head); } return false; } @@ -195,31 +197,29 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andListen) { #if defined _WIN32 - if (!socketInit && !Jupiter::Socket::init()) return false; + if (!socketInit && !Jupiter::Socket::init()) + return false; #endif // _WIN32 Jupiter::Socket::data_->host.set(hostname); Jupiter::Socket::data_->port = iPort; - int i = 0; - static char portString[256]; - sprintf(portString, "%hu", Jupiter::Socket::data_->port); - addrinfo *info = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), portString); - while (info != nullptr) + addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->port).c_str()); + if (info_head != nullptr) { - addrinfo *ainfo = Jupiter::Socket::getAddrInfo(info, i); - if (ainfo == nullptr) + addrinfo *info = info_head; + do { - Jupiter::Socket::freeAddrInfo(info); - return false; - } - Jupiter::Socket::data_->rawSock = socket(ainfo->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); - if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || ::bind(Jupiter::Socket::data_->rawSock, ainfo->ai_addr, ainfo->ai_addrlen) == SOCKET_ERROR) - { - i++; - continue; - } - Jupiter::Socket::freeAddrInfo(info); - if (andListen && Jupiter::Socket::data_->sockType == SOCK_STREAM && listen(Jupiter::Socket::data_->rawSock, SOMAXCONN) == SOCKET_ERROR) return false; - return true; + Jupiter::Socket::data_->rawSock = socket(info->ai_family, Jupiter::Socket::data_->sockType, Jupiter::Socket::data_->sockProto); + if (Jupiter::Socket::data_->rawSock == INVALID_SOCKET || ::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) + { + info = info->ai_next; + continue; + } + Jupiter::Socket::freeAddrInfo(info_head); + if (andListen && Jupiter::Socket::data_->sockType == SOCK_STREAM && ::listen(Jupiter::Socket::data_->rawSock, SOMAXCONN) == SOCKET_ERROR) + return false; + return true; + } while (info != nullptr); + Jupiter::Socket::freeAddrInfo(info_head); } return false; } diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index 4e8b4fe388014dbb8f3b872449a10a0b780cedbd..4e13af1b2d8f0f75a403264f5c346680c1332bc4 100644 GIT binary patch delta 19356 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 QU@Y`gDc785VttAK1y0i#rT_o{ delta 19389 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