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