//------------------------------------------------------------------------------
//
// Select()
//
//------------------------------------------------------------------------------
bool TDSocket::Select(i32 nTimeoutSec, i32 nTimeoutUSec)
{
	bool            bRetVal = false;
	struct timeval *pTimeout = NULL;
	struct timeval  timeout;
	i32           nNumDescriptors = -1;
	i32           nError = 0;

	FD_ZERO(&m_errorFds);
	FD_ZERO(&m_readFds);
	FD_ZERO(&m_writeFds);
	FD_SET(m_socket, &m_errorFds);
	FD_SET(m_socket, &m_readFds);
	FD_SET(m_socket, &m_writeFds);

	//---------------------------------------------------------------------
	// If timeout has been specified then set value, otherwise set timeout
	// to NULL which will block until a descriptor is ready for read/write
	// or an error has occurred.
	//---------------------------------------------------------------------
	if ((nTimeoutSec >= 0) || (nTimeoutUSec >= 0))
	{
		timeout.tv_sec = nTimeoutSec;
		timeout.tv_usec = nTimeoutUSec;
		pTimeout = &timeout;
	}

	nNumDescriptors = SELECT(m_socket + 1, &m_readFds, &m_writeFds, &m_errorFds, pTimeout);
	//    nNumDescriptors = SELECT(m_socket+1, &m_readFds, NULL, NULL, pTimeout);

	//----------------------------------------------------------------------
	// Handle timeout
	//----------------------------------------------------------------------
	if (nNumDescriptors == 0)
	{
		SetSocketError(TDSocket::SocketTimedout);
	}
	//----------------------------------------------------------------------
	// If a file descriptor (read/write) is set then check the
	// socket error (SO_ERROR) to see if there is a pending error.
	//----------------------------------------------------------------------
	else if ((FD_ISSET(m_socket, &m_readFds)) || (FD_ISSET(m_socket, &m_writeFds)))
	{
		i32 nLen = sizeof(nError);

		if (GETSOCKOPT(m_socket, SOL_SOCKET, SO_ERROR, &nError, &nLen) == 0)
		{
			errno = nError;

			if (nError == 0)
			{
				bRetVal = true;
			}
		}

		TranslateSocketError();
	}

	return bRetVal;
}
Exemple #2
0
int udp_set_send_buf(socket_udp *s, int size)
{
        int opt = 0;
        socklen_t opt_size;
        if(SETSOCKOPT (s->fd, SOL_SOCKET, SO_SNDBUF, (const void *)&size,
                        sizeof(size)) != 0) {
                perror("Unable to set socket buffer size");
                return FALSE;
        }

        opt_size = sizeof(opt);
        if(GETSOCKOPT (s->fd, SOL_SOCKET, SO_SNDBUF, (void *)&opt,
                        &opt_size) != 0) {
                perror("Unable to get socket buffer size");
                return FALSE;
        }

        if(opt < size) {
                return FALSE;
        }

        debug_msg("Socket buffer size set to %d B.\n", opt);

        return TRUE;
}
//------------------------------------------------------------------------------
//
// GetSocketDscp() 
//
//------------------------------------------------------------------------------
i32 TDSocket::GetSocketDscp(void)
{
	i32      nTempVal = 0;
	socklen_t  nLen = 0;

	if (IsSocketValid())
	{
		if (GETSOCKOPT(m_socket, IPPROTO_IP, IP_TOS, &nTempVal, &nLen) == SocketError)
		{
			TranslateSocketError();
		}

		nTempVal *= 4;
		nTempVal >>= 4;
	}

	return nTempVal;
}
//------------------------------------------------------------------------------
//
// Flush()
//
//------------------------------------------------------------------------------
bool TDSocket::Flush()
{
	i32 nTcpNoDelay = 1;
	i32 nCurFlags = 0;
	char tmpbuf = 0;
	bool  bRetVal = false;

	//--------------------------------------------------------------------------
	// Get the current setting of the TCP_NODELAY flag.
	//--------------------------------------------------------------------------
	if (GETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(i32)) == 0)
	{
		//----------------------------------------------------------------------
		// Set TCP NoDelay flag
		//----------------------------------------------------------------------
		if (SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nTcpNoDelay, sizeof(i32)) == 0)
		{
			//------------------------------------------------------------------
			// Send empty byte stream to flush the TCP send buffer
			//------------------------------------------------------------------
			if (Send(&tmpbuf, 0) != TDSocket::SocketError)
			{
				bRetVal = true;
			}

			TranslateSocketError();
		}

		//----------------------------------------------------------------------
		// Reset the TCP_NODELAY flag to original state.
		//----------------------------------------------------------------------
		SETSOCKOPT(m_socket, IPPROTO_TCP, TCP_NODELAY, &nCurFlags, sizeof(i32));
	}

	return bRetVal;
}
//------------------------------------------------------------------------------
//
// GetWindowSize() 
//
//------------------------------------------------------------------------------
u16 TDSocket::GetWindowSize(u32 nOptionName)
{
	u32 nTcpWinSize = 0;

	//-------------------------------------------------------------------------
	// no socket given, return system default allocate our own new socket
	//-------------------------------------------------------------------------
	if (m_socket != TDSocket::SocketError)
	{
		socklen_t nLen = sizeof(nTcpWinSize);

		//---------------------------------------------------------------------
		// query for buffer size 
		//---------------------------------------------------------------------
		GETSOCKOPT(m_socket, SOL_SOCKET, nOptionName, &nTcpWinSize, &nLen);
		TranslateSocketError();
	}
	else
	{
		SetSocketError(TDSocket::SocketInvalidSocket);
	}

	return nTcpWinSize;
}
Exemple #6
0
static int socket_connect(CTXTdeclc int *rc, int timeout) {
  int error;
  socklen_t len;
  SOCKET sock_handle;
  int domain, portnum;
  SOCKADDR_IN socket_addr;
    
  domain = (int)ptoc_int(CTXTc 2);
  sock_handle = (SOCKET) ptoc_int(CTXTc 3);
  portnum = (int)ptoc_int(CTXTc 4);

  /** this may not set domain to a valid value; in this case the connect() will fail */
  translate_domain(domain, &domain);
    
  /*** prepare to connect ***/
  FillWithZeros(socket_addr);
  socket_addr.sin_port = htons((unsigned short)portnum);
  socket_addr.sin_family = AF_INET;
  socket_addr.sin_addr.s_addr =
    inet_addr((char*)get_host_IP(ptoc_string(CTXTc 5)));

     
  if (timeout > 0) {
    /* Set up timeout */
	  

    if(! SET_SOCKET_BLOCKING(sock_handle, block_false)) {
      xsb_error("Cannot save options");
      return TIMER_SETUP_ERR;
    }
	  
    /* This will return immediately */
    *rc = connect(sock_handle,(PSOCKADDR)&socket_addr,sizeof(socket_addr));
    error = XSB_SOCKET_ERRORCODE;

    /* restore flags */
    if(! SET_SOCKET_BLOCKING(sock_handle, block_true)) {
      xsb_error("Cannot restore the flags: %d (0x%x)", XSB_SOCKET_ERRORCODE, XSB_SOCKET_ERRORCODE);
      return TIMER_SETUP_ERR;
    }
	  
    /* return and indicate an error immediately unless the connection
     * was successful or the connect is still in progress. */
    if(*rc < 0 && error != EINPROGRESS && error != EWOULDBLOCK) {
      *rc = error;
      return NORMAL_TERMINATION; /* Since it didn't time out */
    }
	  
    /* Wait until the connect is completed (or a timeout occurs) */
    error = write_select(sock_handle, timeout);
	  
    if(error == 0) {
      closesocket(sock_handle);
      *rc = XSB_SOCKET_ERRORCODE;
      return TIMED_OUT;
    }
	  
    /* Get the return code from the connect */
    len=sizeof(error);
    error = GETSOCKOPT(sock_handle, SOL_SOCKET, SO_ERROR, &error, &len);
    if(error < 0) {
      xsb_error("GETSOCKOPT failed");
      *rc = error;
      return NORMAL_TERMINATION; /* Since it didn't time out */
    }
	  
    /* error=0 means success, otherwise it contains the errno */
    if(error) {
      *rc = error;
      return NORMAL_TERMINATION; /* Since it didn't time out */
    }
	  
    *rc = (int)sock_handle;
    return NORMAL_TERMINATION;
  } else {
    *rc = connect(sock_handle,(PSOCKADDR)&socket_addr,sizeof(socket_addr));
    return NORMAL_TERMINATION;
  }
}