topical media & game development

talk show tell print

lib-of-vs-addons-ofxNetwork-src-ofxTCPManager.cpp / cpp



  include <ofxTCPManager.h>
  include <stdio.h>
  
  //--------------------------------------------------------------------------------
  bool ofxTCPManager::m_bWinsockInit= false;
  
  //--------------------------------------------------------------------------------
  ofxTCPManager::ofxTCPManager()
  {
    // was winsock initialized?
            #ifdef TARGET_WIN32
                  if (!m_bWinsockInit) {
                          unsigned short vr;
                          WSADATA        wsaData;
                          vr = MAKEWORD(2,        2);
                          WSAStartup(vr, &wsaData);
                          m_bWinsockInit=        true;
                  }
          #else
                  //this disables the other apps from shutting down if the client
                  //or server disconnects.
                  signal(SIGPIPE,SIG_IGN);
                  signal(EPIPE,SIG_IGN);
          #endif
  
    nonBlocking = false;
    m_hSocket= INVALID_SOCKET;
    m_dwTimeoutSend= OF_TCP_DEFAULT_TIMEOUT;
    m_dwTimeoutReceive= OF_TCP_DEFAULT_TIMEOUT;
    m_dwTimeoutAccept= OF_TCP_DEFAULT_TIMEOUT;
    m_iListenPort= -1;
  };
  
  //--------------------------------------------------------------------------------
  
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(false); #ifdef TARGET_WIN32 if(closesocket(m_hSocket) == SOCKET_ERROR) #else if(close(m_hSocket) == SOCKET_ERROR) #endif { return(false); } m_hSocket= INVALID_SOCKET; #ifdef TARGET_WIN32 //This was commented out in the original //WSACleanup(); #endif return(true); } void ofxTCPManager::CleanUp() { #ifdef TARGET_WIN32 WSACleanup(); #endif m_bWinsockInit = false; } //-------------------------------------------------------------------------------- bool ofxTCPManager::Create() { if (m_hSocket != INVALID_SOCKET) return(false); m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_IP); return(m_hSocket != INVALID_SOCKET); } //-------------------------------------------------------------------------------- bool ofxTCPManager::Listen(int iMaxConnections) { if (m_hSocket == INVALID_SOCKET) return(false); m_iMaxConnections = iMaxConnections; return(listen(m_hSocket, iMaxConnections) != SOCKET_ERROR); } bool ofxTCPManager::Bind(unsigned short usPort) { struct sockaddr_in local; memset(&local, 0, sizeof(sockaddr_in)); local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; //Port MUST be in Network Byte Order local.sin_port = htons(usPort); if (bind(m_hSocket,(struct sockaddr*)&local,sizeof(local))) return false; return true; } //-------------------------------------------------------------------------------- bool ofxTCPManager::Accept(ofxTCPManager& sConnect) { sockaddr_in addr; #ifndef TARGET_WIN32 socklen_t iSize; #else int iSize; #endif if (m_hSocket == INVALID_SOCKET) return(false); if (m_dwTimeoutAccept != NO_TIMEOUT) { fd_set fd= {1, m_hSocket}; timeval tv= {m_dwTimeoutAccept, 0}; if(select(0, &fd, NULL, NULL, &tv) == 0) { return(false); } } iSize= sizeof(sockaddr_in); sConnect.m_hSocket= accept(m_hSocket, (sockaddr*)&addr, &iSize); return(sConnect.m_hSocket != INVALID_SOCKET); } //-------------------------------------------------------------------------------- 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); return(connect(m_hSocket, (sockaddr *)&addr_in, sizeof(sockaddr)) != SOCKET_ERROR); } //--------------------------------------------------------------------------------
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 return (retVal >= 0); } //-------------------------------------------------------------------------------- int ofxTCPManager::Write(const char* pBuff, const int iSize) { int iBytesSent= 0; int iBytesTemp; const char* pTemp= pBuff; do { iBytesTemp= Send(pTemp, iSize - iBytesSent); // error occured? if (iBytesTemp == SOCKET_ERROR) return(SOCKET_ERROR); if (iBytesTemp == SOCKET_TIMEOUT) return(SOCKET_TIMEOUT); iBytesSent+= iBytesTemp; pTemp+= iBytesTemp; } while(iBytesSent < iSize); return(iBytesSent); } //-------------------------------------------------------------------------------- //Theo added - alternative to GetTickCount for windows //This version returns the milliseconds since the unix epoch //Should be good enough for what it is being used for here //(mainly time comparision) ifndef TARGET_WIN32 unsigned long GetTickCount(){ timeb bsdTime; ftime(&bsdTime); unsigned long msSinceUnix = (bsdTime.time*1000) + bsdTime.millitm; return msSinceUnix; } endif //--------------------------------------------------------------------------------
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= {m_dwTimeoutSend, 0}; if(select(m_hSocket+1,NULL,&fd,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } } return(send(m_hSocket, pBuff, iSize, 0)); } //--------------------------------------------------------------------------------
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; while (total < iSize) { ret = send(m_hSocket, pBuff + total, bytesleft, 0); if (ret == -1) { break; } total += ret; bytesleft -=ret; if (GetTickCount() - timestamp > m_dwTimeoutSend * 1000) return SOCKET_TIMEOUT; } return ret==-1 && bytesleft == iSize?SOCKET_ERROR:total; } //--------------------------------------------------------------------------------
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); } } return(recv(m_hSocket, pBuff, iSize, 0)); } //--------------------------------------------------------------------------------
Return values:
SOCKET_TIMEOUT indicates timeout
SOCKET_ERROR in case of a problem.
int ofxTCPManager::ReceiveAll(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,&fd,NULL,NULL,&tv)== 0) { return(SOCKET_TIMEOUT); } } int totalBytes=0; unsigned long stamp = GetTickCount(); do { int ret= recv(m_hSocket, pBuff+totalBytes, iSize-totalBytes, 0); if (ret==0 && totalBytes != iSize) return SOCKET_ERROR; if (ret < 0) return SOCKET_ERROR; if (GetTickCount() - timestamp > m_dwTimeoutReceive * 1000) return SOCKET_TIMEOUT; totalBytes += ret; #ifndef TARGET_WIN32 usleep(20000); //should be 20ms #else Sleep(20); #endif if (GetTickCount() - stamp > 10000) return SOCKET_TIMEOUT; }while(totalBytes < iSize); /* if (totalBytes > 0) { char out[400]; sprintf(out, "\%d bytes received:", totalBytes); int len = strlen(out); memcpy((char*)out + len, pBuff, totalBytes); len += totalBytes; out[len] = 0; OutputDebugString(out); } */ return totalBytes; } //-------------------------------------------------------------------------------- bool ofxTCPManager::GetRemoteAddr(LPINETADDR pInetAddr) { if (m_hSocket == INVALID_SOCKET) return(false); #ifndef TARGET_WIN32 socklen_t iSize; #else int iSize; #endif iSize= sizeof(sockaddr); return(getpeername(m_hSocket, (sockaddr *)pInetAddr, &iSize) != SOCKET_ERROR); } //-------------------------------------------------------------------------------- bool ofxTCPManager::GetInetAddr(LPINETADDR pInetAddr) { if (m_hSocket == INVALID_SOCKET) return(false); #ifndef TARGET_WIN32 socklen_t iSize; #else int iSize; #endif iSize= sizeof(sockaddr); return(getsockname(m_hSocket, (sockaddr *)pInetAddr, &iSize) != SOCKET_ERROR); } void ofxTCPManager::SetTimeoutSend(int timeoutInSeconds) { m_dwTimeoutSend= timeoutInSeconds; } void ofxTCPManager::SetTimeoutReceive(int timeoutInSeconds) { m_dwTimeoutReceive= timeoutInSeconds; } void ofxTCPManager::SetTimeoutAccept(int timeoutInSeconds) { m_dwTimeoutAccept= timeoutInSeconds; } int ofxTCPManager::GetTimeoutSend() { return m_dwTimeoutSend; } int ofxTCPManager::GetTimeoutReceive() { return m_dwTimeoutReceive; } int ofxTCPManager::GetTimeoutAccept() { return m_dwTimeoutAccept; } int ofxTCPManager::GetReceiveBufferSize() { if (m_hSocket == INVALID_SOCKET) return(false); #ifndef TARGET_WIN32 socklen_t size; #else int size; #endif int sizeBuffer=0; size = sizeof(int); getsockopt(m_hSocket, SOL_SOCKET, SO_RCVBUF, (char*)&sizeBuffer, &size); return sizeBuffer; } bool ofxTCPManager::SetReceiveBufferSize(int sizeInByte) { if (m_hSocket == INVALID_SOCKET) return(false); if ( setsockopt(m_hSocket, SOL_SOCKET, SO_RCVBUF, (char*)&sizeInByte, sizeof(sizeInByte)) == 0) return true; else return false; } int ofxTCPManager::GetSendBufferSize() { if (m_hSocket == INVALID_SOCKET) return(false); #ifndef TARGET_WIN32 socklen_t size; #else int size; #endif int sizeBuffer=0; size = sizeof(int); getsockopt(m_hSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sizeBuffer, &size); return sizeBuffer; } bool ofxTCPManager::SetSendBufferSize(int sizeInByte) { if (m_hSocket == INVALID_SOCKET) return(false); if ( setsockopt(m_hSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sizeInByte, sizeof(sizeInByte)) == 0) return true; else return false; } int ofxTCPManager::GetMaxConnections() { return m_iMaxConnections; } bool ofxTCPManager::CheckHost(const char *pAddrStr) { hostent * hostEntry; in_addr iaHost; iaHost.s_addr = inet_addr(pAddrStr); hostEntry = gethostbyaddr((const char *)&iaHost, sizeof(struct in_addr), AF_INET); return ((!hostEntry) ? false : true); }


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.