Beispiel #1
0
LightweightConduit::LightweightConduit(
    NetworkDevice* _nd, 
    uint16 port,
    bool enableReceive, 
    bool enableBroadcast) : Conduit(_nd) {

    if (nd->debugLog) {nd->debugLog->print("Creating a UDP socket        ");}
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    if (sock == SOCKET_ERROR) {
        sock = 0;
        if (nd->debugLog) {
            nd->debugLog->println("FAIL");
            nd->debugLog->println(socketErrorCode());
        }
        return;
    }
    if (nd->debugLog) {nd->debugLog->println("Ok");}

    if (enableReceive) {
        debugAssert(port != 0);
        nd->bind(sock, NetAddress(0, port));
    }

    // Figuring out the MTU seems very complicated, so we just set it to 1000,
    // which is likely to be safe.  See IP_MTU for more information.
    MTU = 1000;

    increaseBufferSize(sock, nd->debugLog);

    if (enableBroadcast) {
        int TR = true;
        if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, 
                       (const char*)&TR, sizeof(TR)) != 0) {
            if (nd->debugLog) {
                nd->debugLog->println("Call to setsockopt failed");
                nd->debugLog->println(socketErrorCode());
            }
            nd->closesocket(sock);
            return;
        }
    }

    if (nd->debugLog) {
        nd->debugLog->printf("Done creating UDP socket %d\n", sock);
    }

    alreadyReadMessage = false;
}
Beispiel #2
0
ReliableConduit::ReliableConduit
   (const NetAddress&   _addr) : 
    state(NO_MESSAGE), 
    receiveBuffer(NULL),
    receiveBufferTotalSize(0), 
    receiveBufferUsedSize(0) {

    NetworkDevice* nd = NetworkDevice::instance();
    
    messageType         = 0;

    addr = _addr;
    Log::common()->print("Creating a TCP socket       ");
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    
    if (sock == SOCKET_ERROR) {
        Log::common()->println("FAIL");
        Log::common()->println(socketErrorCode());
        nd->closesocket(sock);
        return;
    }

    Log::common()->println("Ok");

    // Setup socket options (both constructors should set the same options)

    // Disable Nagle's algorithm (we send lots of small packets)
    const int T = true;
    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, 
                   (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
        
        Log::common()->println("WARNING: Disabling Nagel's "
                              "algorithm failed.");
        Log::common()->println(socketErrorCode());
    } else {
        Log::common()->println("Disabled Nagel's algorithm.");
    }

    // Set the NO LINGER option so the socket doesn't hang around if
    // there is unsent data in the queue when it closes.
    struct linger ling;
    ling.l_onoff  = 0;
    ling.l_linger = 0;
    if (setsockopt(sock, SOL_SOCKET, SO_LINGER, 
                   (const char*)&ling, sizeof(ling)) == SOCKET_ERROR) {
        
        Log::common()->println("WARNING: Setting socket no linger failed.");
        Log::common()->println(socketErrorCode());
    } else {
        Log::common()->println("Set socket option no_linger.");
    }

    // Set reuse address so that a new server can start up soon after
    // an old one has closed.
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 
                   (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
        
        Log::common()->println("WARNING: Setting socket reuseaddr failed.");
        Log::common()->println(socketErrorCode());
    } else {
        Log::common()->println("Set socket option reuseaddr.");
    }

    // Ideally, we'd like to specify IPTOS_LOWDELAY as well.

    logSocketInfo(sock);

    increaseBufferSize(sock);

    Log::common()->printf("Created TCP socket %d\n", sock);

    std::string x = addr.toString();
    Log::common()->printf("Connecting to %s on TCP socket %d   ", x.c_str(), sock);

    int ret = connect(sock, (struct sockaddr *) &(addr.addr), sizeof(addr.addr));

    if (ret == WSAEWOULDBLOCK) {
        RealTime t = System::time() + 5.0;
        // Non-blocking; we must wait until select returns non-zero
        while ((selectOneWriteSocket(sock) == 0) && (System::time() < t)) {
            System::sleep(0.02);
        }

        // TODO: check for failure on the select call

    } else if (ret != 0) {
        sock = (SOCKET)SOCKET_ERROR;
        Log::common()->println("FAIL");
        Log::common()->println(socketErrorCode());
        return;
    }

    Log::common()->println("Ok");
}