//-------------------------------------------------------------------------------- /// 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){ auto ret = WaitSend(m_dwTimeoutSend,0); if(ret!=0){ return ret; } } return send(m_hSocket, pBuff, iSize, 0); }
//-------------------------------------------------------------------------------- /// 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){ auto ret = WaitSend(m_dwTimeoutSend,0); if(ret!=0){ return ret; } } 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)); }
//-------------------------------------------------------------------------------- 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; }
/** * \brief 等待套接口准备好写入操作 * \return 是否成功 * -1,表示操作失败 * 0,表示操作超时 * 1,表示等待成功,套接口已经可以写入数据 */ int CSocket::waitForWrite() { printf("CSocket::waitForWrite\n"); if( m_bUseIocp ) { return WaitSend( true, wr_msec ); } struct mypollfd pfd; pfd.fd = sock; pfd.events = POLLOUT | POLLPRI; pfd.revents = 0; int retcode = ::poll(&pfd,1,wr_msec); if (retcode > 0 && 0 == (pfd.revents & POLLOUT)) retcode = -1; return retcode; }
/** * \brief 等待套接口准备好写入操作 * \return 是否成功 * -1,表示操作失败 * 0,表示操作超时 * 1,表示等待成功,套接口已经可以写入数据 */ int CSocket::checkIOForWrite() { //Zebra::logger->debug("CSocket::checkIOForWrite"); if( m_bUseIocp ) // 使用Iocp时随时都可以写入数据 { return WaitSend( false ); } struct mypollfd pfd; pfd.fd = sock; pfd.events = POLLOUT | POLLPRI; pfd.revents = 0; int retcode = ::poll(&pfd,1,0); if (retcode > 0 && 0 == (pfd.revents & POLLOUT)) retcode = -1; return retcode; }
//-------------------------------------------------------------------------------- /// Return values: /// SOCKET_TIMEOUT indicates timeout /// SOCKET_ERROR in case of a problem. int ofxUDPManager::SendAll(const char* pBuff, const int iSize) { if (m_hSocket == INVALID_SOCKET) return(SOCKET_ERROR); auto timestamp = ofGetElapsedTimeMicros(); auto timeleftSecs = m_dwTimeoutSend; auto timeleftMicros = 0; int total= 0; int bytesleft = iSize; int ret=-1; while (total < iSize) { if (m_dwTimeoutSend != NO_TIMEOUT){ auto ret = WaitSend(timeleftSecs,timeleftMicros); if(ret!=0){ return ret; } } ret = sendto(m_hSocket, (char*)pBuff, iSize, 0, (sockaddr *)&saClient, sizeof(sockaddr)); if (ret == SOCKET_ERROR) { return SOCKET_ERROR; } total += ret; bytesleft -=ret; if (m_dwTimeoutSend != NO_TIMEOUT){ auto now = ofGetElapsedTimeMicros(); auto diff = now - timestamp; if (diff > m_dwTimeoutSend * 1000000){ return SOCKET_TIMEOUT; } float timeFloat = m_dwTimeoutSend - diff/1000000.; timeleftSecs = timeFloat; timeleftMicros = (timeFloat - timeleftSecs) * 1000000; } } return total; }