//------------------------------------------------------------------------------ // // 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; }
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; }
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; } }