static bool connectSocket (std::atomic<int>& handle, CriticalSection& readLock, const String& hostName, int portNumber, int timeOutMillisecs) noexcept { bool success = false; if (auto* info = getAddressInfo (false, hostName, portNumber)) { for (auto* i = info; i != nullptr; i = i->ai_next) { auto newHandle = socket (i->ai_family, i->ai_socktype, 0); if (newHandle != invalidSocket) { setSocketBlockingState (newHandle, false); auto result = ::connect (newHandle, i->ai_addr, (socklen_t) i->ai_addrlen); success = (result >= 0); if (! success) { #if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) #endif { std::atomic<int> cvHandle { (int) newHandle }; if (waitForReadiness (cvHandle, readLock, false, timeOutMillisecs) == 1) success = true; } } if (success) { handle = (int) newHandle; break; } #if JUCE_WINDOWS closesocket (newHandle); #else ::close (newHandle); #endif } } freeaddrinfo (info); if (success) { setSocketBlockingState (handle, true); resetSocketOptions (handle, false, false); } } return success; }
bool connectSocket (int volatile& handle, const bool isDatagram, void** serverAddress, const String& hostName, const int portNumber, const int timeOutMillisecs) noexcept { struct addrinfo hints = { 0 }; hints.ai_family = AF_UNSPEC; hints.ai_socktype = isDatagram ? SOCK_DGRAM : SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; struct addrinfo* info = nullptr; if (getaddrinfo (hostName.toUTF8(), String (portNumber).toUTF8(), &hints, &info) != 0 || info == 0) return false; if (handle < 0) handle = (int) socket (info->ai_family, info->ai_socktype, 0); if (handle < 0) { freeaddrinfo (info); return false; } if (isDatagram) { struct sockaddr* s = new struct sockaddr(); *s = *(info->ai_addr); *serverAddress = s; freeaddrinfo (info); return true; } setSocketBlockingState (handle, false); const int result = ::connect (handle, info->ai_addr, (int) info->ai_addrlen); freeaddrinfo (info); if (result < 0) { #if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) #endif { if (waitForReadiness (handle, false, timeOutMillisecs) != 1) { setSocketBlockingState (handle, true); return false; } } } setSocketBlockingState (handle, true); resetSocketOptions (handle, false, false); return true; }
bool StreamingSocket::connect (const String& remoteHostName, const int remotePortNumber, const int timeOutMillisecs) { if (isListener) { jassertfalse // a listener socket can't connect to another one! return false; } if (connected) close(); hostName = remoteHostName; portNumber = remotePortNumber; isListener = false; connected = connectSocket (handle, false, 0, remoteHostName, remotePortNumber, timeOutMillisecs); if (! (connected && resetSocketOptions (handle, false, false))) { close(); return false; } return true; }
StreamingSocket::StreamingSocket (const String& hostName_, const int portNumber_, const int handle_) : hostName (hostName_), portNumber (portNumber_), handle (handle_), connected (true), isListener (false) { #if JUCE_WINDOWS initWin32Sockets(); #endif resetSocketOptions (handle_, false, false); }
DatagramSocket::DatagramSocket (const String& hostName_, const int portNumber_, const int handle_, const int localPortNumber) : hostName (hostName_), portNumber (portNumber_), handle (handle_), connected (true), allowBroadcast (false), serverAddress (0) { #if JUCE_WINDOWS initWin32Sockets(); #endif resetSocketOptions (handle_, true, allowBroadcast); bindToPort (localPortNumber); }
bool connectSocket(int volatile& handle,const std::string& remote_host_name, int remote_port_number,int timeout_millisecs) { struct hostent* const host_ent = gethostbyname (remote_host_name.c_str()); if (host_ent == 0) return false; struct in_addr target_address; memcpy (&target_address.s_addr, *(host_ent->h_addr_list), sizeof (target_address.s_addr)); struct sockaddr_in server_temp_address; memset(&server_temp_address,0,sizeof(sockaddr_in)); server_temp_address.sin_family = PF_INET; server_temp_address.sin_addr = target_address; server_temp_address.sin_port = htons ((u_short) remote_port_number); if (handle < 0) handle = (int) socket (AF_INET, SOCK_STREAM, 0); if (handle < 0) return false; setSocketBlockingState (handle, false); const int result = ::connect (handle, (struct sockaddr*) &server_temp_address, sizeof (struct sockaddr_in)); if (result < 0) { if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) { if (waitForReadiness (handle, false, timeout_millisecs) != 1) { setSocketBlockingState (handle, true); return false; } } } setSocketBlockingState (handle, true); resetSocketOptions (handle); return true; }
static bool connectSocket (int volatile& handle, CriticalSection& readLock, const String& hostName, const int portNumber, const int timeOutMillisecs) noexcept { struct addrinfo* info = getAddressInfo (false, hostName, portNumber); if (info == nullptr) return false; if (handle < 0) handle = (int) socket (info->ai_family, info->ai_socktype, 0); if (handle < 0) { freeaddrinfo (info); return false; } setSocketBlockingState (handle, false); const int result = ::connect (handle, info->ai_addr, (socklen_t) info->ai_addrlen); freeaddrinfo (info); bool retval = (result >= 0); if (result < 0) { #if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) #endif { if (waitForReadiness (handle, readLock, false, timeOutMillisecs) == 1) retval = true; } } setSocketBlockingState (handle, true); if (retval) resetSocketOptions (handle, false, false); return retval; }
bool DatagramSocket::connect (const String& remoteHostName, const int remotePortNumber, const int timeOutMillisecs) { if (connected) close(); hostName = remoteHostName; portNumber = remotePortNumber; connected = connectSocket (handle, true, &serverAddress, remoteHostName, remotePortNumber, timeOutMillisecs); if (! (connected && resetSocketOptions (handle, true, allowBroadcast))) { close(); return false; } return true; }
static bool connectSocket (int volatile& handle, const bool isDatagram, void** serverAddress, const String& hostName, const int portNumber, const int timeOutMillisecs) throw() { struct hostent* const hostEnt = gethostbyname (hostName); if (hostEnt == 0) return false; struct in_addr targetAddress; memcpy (&targetAddress.s_addr, *(hostEnt->h_addr_list), sizeof (targetAddress.s_addr)); struct sockaddr_in servTmpAddr; zerostruct (servTmpAddr); servTmpAddr.sin_family = PF_INET; servTmpAddr.sin_addr = targetAddress; servTmpAddr.sin_port = htons ((uint16) portNumber); if (handle < 0) handle = (int) socket (AF_INET, isDatagram ? SOCK_DGRAM : SOCK_STREAM, 0); if (handle < 0) return false; if (isDatagram) { *serverAddress = new struct sockaddr_in(); *((struct sockaddr_in*) *serverAddress) = servTmpAddr; return true; } setSocketBlockingState (handle, false); const int result = ::connect (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)); if (result < 0) { #if JUCE_WINDOWS if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) #endif { if (waitForReadiness (handle, false, timeOutMillisecs) != 1) { setSocketBlockingState (handle, true); return false; } } } setSocketBlockingState (handle, true); resetSocketOptions (handle, false, false); return true; }