//-------------------------------------------------------------------------------- /// Closes an open socket. /// NOTE: A closed socket cannot be reused again without a call to "Create()". bool ofxTCPManager::Close() { if (m_hSocket == INVALID_SOCKET) return(true); #ifdef TARGET_WIN32 if(closesocket(m_hSocket) == SOCKET_ERROR) #else m_closing = true; shutdown(m_hSocket,SHUT_RDWR); if(close(m_hSocket) == SOCKET_ERROR) #endif { // if it's reported we're not/no longer a socket, let it fall through and be invalidated int Error = ofxNetworkCheckError(); if ( Error != OFXNETWORK_ERROR(NOTSOCK) ) { return(false); } } m_hSocket= INVALID_SOCKET; #ifdef TARGET_WIN32 //This was commented out in the original //WSACleanup(); #endif return(true); }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. /// int ofxTCPManager::Receive(char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET) return(SOCKET_ERROR); if (m_dwTimeoutReceive != NO_TIMEOUT) { fd_set fd; FD_ZERO(&fd); FD_SET(m_hSocket, &fd); timeval tv= {(time_t)m_dwTimeoutSend, 0}; if(select(m_hSocket+1,&fd,NULL,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } } int ret = recv(m_hSocket, pBuff, iSize, 0); if (SOCKET_ERROR == ret) { int err = ofxNetworkCheckError(); if (OFXNETWORK_ERROR(WOULDBLOCK) == err) { // Non-blocking socket, no data to receive ret = 0; } } return ret; }
//-------------------------------------------------------------------------------- bool ofxTCPManager::Connect(const char *pAddrStr, unsigned short usPort) { sockaddr_in addr_in= {0}; struct hostent *he; if (m_hSocket == INVALID_SOCKET){ return(false); } if ((he = gethostbyname(pAddrStr)) == NULL) return(false); addr_in.sin_family= AF_INET; // host byte order addr_in.sin_port = htons(usPort); // short, network byte order addr_in.sin_addr = *((struct in_addr *)he->h_addr); // set to non-blocking before connect bool wasBlocking = nonBlocking; if(m_dwTimeoutConnect != NO_TIMEOUT){ SetNonBlocking(true); } int ret = connect(m_hSocket, (sockaddr *)&addr_in, sizeof(sockaddr)); int err = 0; if(ret<0) err = ofxNetworkCheckError(); // set a timeout if (ret < 0 && (err == OFXNETWORK_ERROR(INPROGRESS) || err == OFXNETWORK_ERROR(WOULDBLOCK)) && m_dwTimeoutConnect != NO_TIMEOUT) { ret = WaitSend(m_dwTimeoutConnect, 0); if(ret == 0) { socklen_t len = sizeof err; if (getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char*)&err, &len)<0){ ret = SOCKET_ERROR; }else if(err != 0) { ret = SOCKET_ERROR; } } } if(m_dwTimeoutConnect != NO_TIMEOUT){ SetNonBlocking(wasBlocking); } return ret>=0; }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. int ofxUDPManager::Receive(char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET){ ofLogError("ofxUDPManager") << "INVALID_SOCKET"; return(SOCKET_ERROR); } /*if (m_dwTimeoutSend != NO_TIMEOUT) { fd_set fd; FD_ZERO(&fd); FD_SET(m_hSocket, &fd); timeval tv= {m_dwTimeoutSend, 0}; if(select(m_hSocket+1,&fd,NULL,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } }*/ #ifndef TARGET_WIN32 socklen_t nLen= sizeof(sockaddr); #else int nLen= sizeof(sockaddr); #endif int ret=0; memset(pBuff, 0, iSize); ret= recvfrom(m_hSocket, pBuff, iSize, 0, (sockaddr *)&saClient, &nLen); if (ret > 0) { //ofLogNotice("ofxUDPManager") << "received from: " << inet_ntoa((in_addr)saClient.sin_addr); canGetRemoteAddress= true; } else { canGetRemoteAddress = false; // if the network error is WOULDBLOCK, then return 0 instead of SOCKET_ERROR as it's not really a problem, just no data. int SocketError = ofxNetworkCheckError(); if ( SocketError == OFXNETWORK_ERROR(WOULDBLOCK) ) return 0; } return ret; // return(recvfrom(m_hSocket, pBuff, iSize, 0)); }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. /// int ofxTCPManager::PeekReceive(char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET) return(SOCKET_ERROR); int ret = recv(m_hSocket, pBuff, iSize, MSG_PEEK); if(ret==-1) { // if socket is non-blocking, the result is likely to be EWOULDBLOCK (no data) so return zero-bytes int NetError = ofxNetworkCheckError(); if ( NetError == OFXNETWORK_ERROR(WOULDBLOCK) ) return 0; // error return SOCKET_ERROR; } return ret; }