Example #1
0
SocketError SocketImpl::bind(const SockAddr& sockAddr) {
    if (socket == INVALID_SOCKET) {
        return SocketError::NotInitialized;
    }

    sockaddr_storage storage;
    sockAddr.toNative(&storage);

    // For bind we also want to set the SO_EXCLUSIVEADDRUSE option
    DWORD opt = 1;
    int optRes = ::setsockopt(socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&opt, sizeof(DWORD));
    if (optRes != 0) {
        return getSocketError(::WSAGetLastError());
    }

    int bindRes = ::bind(socket, (const sockaddr*)&storage, sizeof(sockaddr_storage));
    if (bindRes != 0) {
        return getSocketError(::WSAGetLastError());
    }

    // And then we need to fetch back the bound addr/port
    int nameLen = sizeof(sockaddr_storage);
    int nameRes = ::getsockname(socket, (sockaddr*)&storage, &nameLen);
    if (nameRes != 0) {
        return getSocketError(::WSAGetLastError());
    }

    localAddr = SockAddr::fromNative(&storage);

    return SocketError::Ok;
}
Example #2
0
SocketError SocketImpl::connect(const SockAddr& sockAddr) {
    if (socket == INVALID_SOCKET) {
        return SocketError::NotInitialized;
    }

    sockaddr_storage storage;
    sockAddr.toNative(&storage);

    // For reasons that I presume have to do with DisconnectEx, ConnectEx
    // requires a bound socket
    sockaddr_storage addrAny;
    addrAny.ss_family = storage.ss_family;
    INETADDR_SETANY((sockaddr*)&addrAny);

    int bindRes = ::bind(socket, (const sockaddr*)&addrAny, sizeof(sockaddr_storage));
    if (bindRes != 0) {
        return getSocketError(::WSAGetLastError());
    }

    SocketError res;
    connect_co(sockAddr, &res).get();
    return res;
}