Пример #1
0
// -------------------------------------------------------------
// bindSocket() -- bind the socket to an address, and configure
// the send and receive buffers.
// -------------------------------------------------------------
bool NetHandler::bindSocket()
{
#if defined(WIN32)
    if (socketNum == INVALID_SOCKET) return false;
#else
    if (socketNum < 0) return false;
#endif

    // ---
    // Make sure we have a local host IP address
    // ---
    if (localAddr == INADDR_ANY) {
        char localhost[256];
        int result = gethostname(localhost, sizeof(localhost));
        if (result == 0) {
            setLocalAddr(localhost);
        }
    }

    // ---
    // Set the reuse socket attribute
    // ---
    {
#if defined(WIN32)
        BOOL optval = getSharedFlag();
        Len optlen = sizeof(optval);
        if( setsockopt(socketNum, SOL_SOCKET, SO_REUSEADDR, (const char*) &optval, optlen) == SOCKET_ERROR)
#else
        int optval = getSharedFlag();
        Len optlen = sizeof(optval);
        if( setsockopt(socketNum, SOL_SOCKET, SO_REUSEADDR, &optval, optlen) == SOCKET_ERROR)
#endif
        {
            perror("init(): error setsockopt(SO_REUSEADDR)\n");
            return false;
        }
    }

   return true;
}
Пример #2
0
//------------------------------------------------------------------------------
// serialize
//------------------------------------------------------------------------------
std::ostream& NetHandler::serialize(std::ostream& sout, const int i, const bool slotsOnly) const
{
    int j = 0;
    if ( !slotsOnly ) {
        indent(sout,i);
        sout << "( " << getFormName() << std::endl;
        j = 4;
    }

    if (port != 0) {
        indent(sout,i+j);
        sout << "port: ";
        sout << port;
        sout << std::endl;
    }

    if (localPort != 0) {
        indent(sout,i+j);
        sout << "localPort: ";
        sout << localPort;
        sout << std::endl;
    }

    indent(sout,i+j);
    sout << "shared: ";
    sout << getSharedFlag();
    sout << std::endl;

    BaseClass::serialize(sout,i+j,true);

    if ( !slotsOnly ) {
        indent(sout,i);
        sout << ")" << std::endl;
    }

    return sout;
}
Пример #3
0
// -------------------------------------------------------------
// bindSocket() -- bind the socket to an address, and configure
// the send and receive buffers.
// -------------------------------------------------------------
bool PosixHandler::bindSocket()
{
    if (socketNum == INVALID_SOCKET) return false;

    // ---
    // Set the reuse socket attribute
    // ---
    {
#if defined(WIN32)
        BOOL optval = getSharedFlag();
        socklen_t optlen = sizeof(optval);
        if (::setsockopt(socketNum, SOL_SOCKET, SO_REUSEADDR, (const char*) &optval, optlen) == SOCKET_ERROR) {
#else
        int optval = getSharedFlag();
        socklen_t optlen = sizeof(optval);
        if (::setsockopt(socketNum, SOL_SOCKET, SO_REUSEADDR, &optval, optlen) == SOCKET_ERROR) {
#endif
            std::perror("PosixHandler::bindSocket(): error setsockopt(SO_REUSEADDR)\n");
            return false;
        }
    }

    return true;
}

//------------------------------------------------------------------------------
// Set the output buffer size
//------------------------------------------------------------------------------
bool PosixHandler::setSendBuffSize()
{
   if (socketNum == INVALID_SOCKET) return false;

   const unsigned int optval = sendBuffSizeKb * 1024;
   socklen_t optlen = sizeof(optval);
#if defined(WIN32)
   if (::setsockopt(socketNum, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char*>(&optval), optlen) == SOCKET_ERROR) {
#else
   if (::setsockopt(socketNum, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const void*>(&optval), optlen) == SOCKET_ERROR) {
#endif
      std::perror("PosixHandler::setSendBuffSize(): error setting the send buffer size\n");
      return false;
   }
   return true;
}

//------------------------------------------------------------------------------
// Sets the input buffer size
//------------------------------------------------------------------------------
bool PosixHandler::setRecvBuffSize()
{
   if (socketNum == INVALID_SOCKET) return false;

   const unsigned int optval = recvBuffSizeKb * 1024;
   socklen_t optlen = sizeof (optval);
#if defined(WIN32)
   if (::setsockopt(socketNum, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char*>(&optval), optlen) == SOCKET_ERROR) {
#else
   if (::setsockopt(socketNum, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const void*>(&optval), optlen) == SOCKET_ERROR) {
#endif
      std::perror("PosixHandler::setRecvBuffSize(): error setting the receive buffer size\n");
      return false;
   }
   return true;
}

// -------------------------------------------------------------
// setBlocked() -- Sets blocked I/O mode
// -------------------------------------------------------------
bool PosixHandler::setBlocked()
{
    if (socketNum == NET_INVALID_SOCKET) return false;

// Set the socket 'sock' to Blocking. Wait I/O.
#if defined(WIN32)
    unsigned long zz = false;
    if (::ioctlsocket(socketNum, FIONBIO, &zz) == SOCKET_ERROR) {
        std::perror("PosixHandler::setBlocked()");
        return false;
    }
#else
    const int zz = 0;
    if (::ioctl(socketNum, FIONBIO, &zz) == SOCKET_ERROR) {
        std::perror("PosixHandler::setBlocked()");
        return false;
    }
#endif

   return true;
}

// -------------------------------------------------------------
// setNoWait() -- Sets no wait (non-blocking) I/O mode
// -------------------------------------------------------------
bool PosixHandler::setNoWait()
{
    if (socketNum == NET_INVALID_SOCKET) return false;

// Set the socket 'sock' to Non-Blocking. Nowait I/O.
#if defined(WIN32)
    unsigned long zz = true;
    if (::ioctlsocket(socketNum, FIONBIO, &zz ) == SOCKET_ERROR) {
        std::perror("PosixHandler::setNoWait()");
        return false;
    }
#else
    const int zz = 1;
    if (::ioctl(socketNum, FIONBIO, &zz ) == SOCKET_ERROR) {
        std::perror("PosixHandler::setNoWait()");
        return false;
    }
#endif

   return true;
}

// -------------------------------------------------------------
// Returns true if the network handler has been initialized
// -------------------------------------------------------------
bool PosixHandler::isConnected() const
{
    return initialized;
}

// -------------------------------------------------------------
// Close (un-initialize) this network
// -------------------------------------------------------------
bool PosixHandler::closeConnection()
{
    initialized = false;
    return true;
}

// -------------------------------------------------------------
// sendData() -- Send data
// -------------------------------------------------------------
bool PosixHandler::sendData(const char* const packet, const int size)
{
    if (socketNum == INVALID_SOCKET) return false;

    // Send the data
    struct sockaddr_in addr;        // Working address structure
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = netAddr;
    addr.sin_port = htons(port);
    socklen_t addrlen = sizeof(addr);
    int result = ::sendto(socketNum, packet, size, 0, reinterpret_cast<const struct sockaddr*>(&addr), addrlen);
    if (result == SOCKET_ERROR) {
#if defined(WIN32)
        int err = ::WSAGetLastError();
        if (isMessageEnabled(MSG_ERROR)) {
            std::cerr << "PosixHandler::sendData(): sendto error: " << err << " hex=0x" << std::hex << err << std::dec << std::endl;
        }
#else
        std::perror("PosixHandler::sendData(): sendto error msg");
        if (isMessageEnabled(MSG_ERROR)) {
            std::cerr << "PosixHandler::sendData(): sendto error result: " << result << std::endl;
        }
#endif
        return false;
    }
    return true;
}

// -------------------------------------------------------------
// recvData() -- Receive data and possible ignore our own
//               local port messages.
// -------------------------------------------------------------
unsigned int PosixHandler::recvData(char* const packet, const int maxSize)
{
   unsigned int n = 0;

   if (socketNum == INVALID_SOCKET) return 0;

   fromAddr1 = INADDR_NONE;
   fromPort1 = 0;

   bool tryAgain = true;
   while (tryAgain) {
      tryAgain = false;

      // Try to receive the data
      struct sockaddr_in raddr;       // IP address
      socklen_t addrlen = sizeof(raddr);
      int result = ::recvfrom(socketNum, packet, maxSize, 0, reinterpret_cast<struct sockaddr*>(&raddr), &addrlen);

      if (result > 0 && ignoreSourcePort != 0) {
         // Ok we have one; make sure it's not one we should ignore
         uint16_t rport = ntohs(raddr.sin_port);
         if (rport == ignoreSourcePort) {
            tryAgain = true;
         }
      }

      // set number of bytes received
      if (result > 0 && !tryAgain) {
         n = result;
         fromAddr1 = raddr.sin_addr.s_addr;
         fromPort1 = ntohs(raddr.sin_port);
      }
   }
   return n;
}

//------------------------------------------------------------------------------
// Set functions
//------------------------------------------------------------------------------

// Set the shared flag
void PosixHandler::setSharedFlag(const bool b)
{
   sharedFlg = b;
}

// Set port number
bool PosixHandler::setPort(const uint16_t n1)
{
   port = n1;
   return true;
}