//-------------------------------------------------------------------------------- int ofxUDPManager::GetSendBufferSize() { if (m_hSocket == INVALID_SOCKET) return(false); int sizeBuffer=0; #ifndef TARGET_WIN32 socklen_t size = sizeof(int); #else int size = sizeof(int); #endif int ret = getsockopt(m_hSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sizeBuffer, &size); if(ret==-1) ofxNetworkCheckError(); return sizeBuffer; }
//-------------------------------------------------------------------------------- /// 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 { ofxNetworkCheckError(); //ofLogNotice("ofxUDPManager") << "received from: ????"; canGetRemoteAddress= false; } return ret; // return(recvfrom(m_hSocket, pBuff, iSize, 0)); }
//-------------------------------------------------------------------------------- ///Theo added - Choose to set nonBLocking - default mode is to block bool ofxTCPManager::SetNonBlocking(bool useNonBlocking) { nonBlocking = useNonBlocking; #ifdef TARGET_WIN32 unsigned long arg = nonBlocking; int retVal = ioctlsocket(m_hSocket,FIONBIO,&arg); #else int arg = nonBlocking; int retVal = ioctl(m_hSocket,FIONBIO,&arg); #endif bool ret = (retVal >= 0); if(!ret) ofxNetworkCheckError(); return ret; }
//-------------------------------------------------------------------------------- bool ofxTCPManager::Connect(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 #ifdef TARGET_WIN32 unsigned long iMode = 1; if (m_dwTimeoutConnect != NO_TIMEOUT) ioctlsocket(m_hSocket, FIONBIO, &iMode); #else if (m_dwTimeoutConnect != NO_TIMEOUT) fcntl(m_hSocket, F_SETFL, O_NONBLOCK); #endif bool ret = (connect(m_hSocket, (sockaddr *)&addr_in, sizeof(sockaddr)) != SOCKET_ERROR); // set a timeout if (m_dwTimeoutConnect != NO_TIMEOUT) { fd_set fd; FD_ZERO(&fd); FD_SET(m_hSocket, &fd); timeval tv= {(time_t)m_dwTimeoutConnect, 0}; if(select(m_hSocket+1,NULL,&fd,NULL,&tv)== 1) { int so_error; socklen_t len = sizeof so_error; getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char*)&so_error, &len); if (so_error == 0) { return true; } } } if(!ret) ofxNetworkCheckError(); return ret; }
//-------------------------------------------------------------------------------- /// Closes an open socket. /// NOTE: A closed socket cannot be reused again without a call to "Create()". bool ofxUDPManager::Close() { if (m_hSocket == INVALID_SOCKET) return(false); #ifdef TARGET_WIN32 if(closesocket(m_hSocket) == SOCKET_ERROR) #else if(close(m_hSocket) == SOCKET_ERROR) #endif { ofxNetworkCheckError(); return(false); } m_hSocket= INVALID_SOCKET; return(true); }
//-------------------------------------------------------------------------------- /// 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; }
//-------------------------------------------------------------------------------- /// 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_dwTimeoutReceive != NO_TIMEOUT){ auto ret = WaitReceive(m_dwTimeoutReceive,0); if(ret!=0){ return ret; } } #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)); }
//-------------------------------------------------------------------------------- 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 ofxTCPManager::Receive(char* pBuff, const int iSize) { if (m_hSocket == 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); } } int ret = recv(m_hSocket, pBuff, iSize, 0); if(ret==-1) ofxNetworkCheckError(); return ret; }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. int ofxTCPManager::Send(const char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET) return(SOCKET_ERROR); if (m_dwTimeoutSend != NO_TIMEOUT) { fd_set fd; FD_ZERO(&fd); FD_SET(m_hSocket, &fd); timeval tv= {static_cast<__darwin_time_t>(m_dwTimeoutSend), 0}; if(select(m_hSocket+1,NULL,&fd,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } } int ret = send(m_hSocket, pBuff, iSize, 0); if(ret==-1) ofxNetworkCheckError(); return ret; }
//-------------------------------------------------------------------------------- bool ofxTCPManager::Connect(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); bool ret = (connect(m_hSocket, (sockaddr *)&addr_in, sizeof(sockaddr)) != SOCKET_ERROR); if(!ret) ofxNetworkCheckError(); return ret; }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. int ofxUDPManager::Send(const char* pBuff, const int iSize) { if (m_hSocket == 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,NULL,&fd,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } }*/ int ret = sendto(m_hSocket, (char*)pBuff, iSize, 0, (sockaddr *)&saClient, sizeof(sockaddr)); if(ret==-1) ofxNetworkCheckError(); return ret; // return(send(m_hSocket, pBuff, iSize, 0)); }
//-------------------------------------------------------------------------------- /// 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 if(close(m_hSocket) == SOCKET_ERROR) #endif { ofxNetworkCheckError(); return(false); } m_hSocket= INVALID_SOCKET; #ifdef TARGET_WIN32 //This was commented out in the original //WSACleanup(); #endif return(true); }
//-------------------------------------------------------------------------------- int ofxUDPManager::GetTTL() { if (m_hSocket == INVALID_SOCKET) return(false); int nTTL; #ifndef TARGET_WIN32 socklen_t nSize = sizeof(int); #else int nSize = sizeof(int); #endif if (getsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char FAR *) &nTTL, &nSize) == SOCKET_ERROR) { #ifdef _DEBUG printf("getsockopt failed! Error: %d", WSAGetLastError()); #endif ofxNetworkCheckError(); return -1; } return nTTL; }
//-------------------------------------------------------------------------------- bool ofxUDPManager::BindMcast(char *pMcast, unsigned short usPort) { // bind to port if (!Bind(usPort)) { printf("can't bind to port \n"); return false; } // join the multicast group struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(pMcast); mreq.imr_interface.s_addr = INADDR_ANY; if (setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR*) &mreq, sizeof (mreq)) == SOCKET_ERROR) { ofxNetworkCheckError(); return false; } printf("here ? \n"); // multicast bind successful return true; }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. int ofxTCPManager::SendAll(const char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET) return(SOCKET_ERROR); unsigned long timestamp= GetTickCount(); 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,NULL,&fd,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } } int total= 0; int bytesleft = iSize; int ret=-1; int err = 0; while (total < iSize) { ret = send(m_hSocket, pBuff + total, bytesleft, 0); if (ret == -1) { err = ofxNetworkCheckError(); break; } total += ret; bytesleft -=ret; if (GetTickCount() - timestamp > m_dwTimeoutSend * 1000) return SOCKET_TIMEOUT; } if(err == EPIPE){ Close(); return 0; } return ret==-1 && bytesleft == iSize?SOCKET_ERROR:total; }