예제 #1
0
DWORD Socket::getOutputTimeout()
{
	DWORD timeout = 0;
#if defined(WIN32) || defined(WIN64)
	getSocketOption( SO_SNDTIMEO, timeout );
#endif
	return timeout;
}
예제 #2
0
bool CPPTcpClientSocket::connect(short port, unsigned int addr, int timeout, bool spin){
    std::lock_guard<std::mutex> lockR(recvLock), lockS(sendLock);
    m_port = port;
    m_addr = addr;
    struct sockaddr_in remote;
    memset(&remote, 0, sizeof(remote));
    remote.sin_family = AF_INET;
    remote.sin_addr.s_addr = m_addr;
    remote.sin_port = htons(m_port);
    double tremaining = timeout;
    auto start = std::chrono::system_clock::now();
    bool success = false;    
    do{
        if (!open()){
            break;
        }
        setBlocking(false, false);
        if (::connect(m_sock, (struct sockaddr *)&remote, sizeof(remote)) == 0){
            success = true;
            break;
        }
        if (errno != EINPROGRESS){
            break;
        }
        struct pollfd pfd = {m_sock, POLLWRNORM, 0};
        if (poll(&pfd, 1, (int)tremaining) > 0){
            int optionValue = -1;
            socklen_t optionLength = sizeof(optionValue);
            if (getSocketOption(SOL_SOCKET, SO_ERROR, (void *)&optionValue, &optionLength, false) && optionValue == 0){
                success = true;
                break;
            }
        }
        std::chrono::duration<double, std::milli> dur = std::chrono::system_clock::now() - start;
        tremaining = timeout - dur.count();
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        ::shutdown(m_sock, SHUT_RDWR);
        ::close(m_sock);
        m_sock = -1;
        if (!spin) break;
        
    }while((tremaining > 0.0 || timeout < 0) && !sigClose);
    setBlocking(true, false);
    if (success) return true;
    
    if (m_sock != -1){
        ::shutdown(m_sock, SHUT_RDWR);
        ::close(m_sock);
        m_sock=-1;
    }
    return false;
}
예제 #3
0
static jobject OSNetworkSystem_getSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option) {
    NetFd fd(env, fileDescriptor);
    if (fd.isClosed()) {
        return NULL;
    }

    int family = getSocketAddressFamily(fd.get());
    if (family != AF_INET && family != AF_INET6) {
        jniThrowSocketException(env, EAFNOSUPPORT);
        return NULL;
    }

    switch (option) {
    case JAVASOCKOPT_TCP_NODELAY:
        return getSocketOption_Boolean(env, fd, IPPROTO_TCP, TCP_NODELAY);
    case JAVASOCKOPT_SO_SNDBUF:
        return getSocketOption_Integer(env, fd, SOL_SOCKET, SO_SNDBUF);
    case JAVASOCKOPT_SO_RCVBUF:
        return getSocketOption_Integer(env, fd, SOL_SOCKET, SO_RCVBUF);
    case JAVASOCKOPT_SO_BROADCAST:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_BROADCAST);
    case JAVASOCKOPT_SO_REUSEADDR:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_REUSEADDR);
    case JAVASOCKOPT_SO_KEEPALIVE:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_KEEPALIVE);
    case JAVASOCKOPT_SO_OOBINLINE:
        return getSocketOption_Boolean(env, fd, SOL_SOCKET, SO_OOBINLINE);
    case JAVASOCKOPT_IP_TOS:
        if (family == AF_INET) {
            return getSocketOption_Integer(env, fd, IPPROTO_IP, IP_TOS);
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_TCLASS);
        }
    case JAVASOCKOPT_SO_LINGER:
        {
            linger lingr;
            bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &lingr);
            if (!ok) {
                return NULL; // We already threw.
            } else if (!lingr.l_onoff) {
                return booleanValueOf(env, false);
            } else {
                return integerValueOf(env, lingr.l_linger);
            }
        }
    case JAVASOCKOPT_SO_TIMEOUT:
        {
            timeval timeout;
            bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout);
            return ok ? integerValueOf(env, toMs(timeout)) : NULL;
        }
#ifdef ENABLE_MULTICAST
    case JAVASOCKOPT_IP_MULTICAST_IF:
        {
            // Although setsockopt(2) can take an ip_mreqn for IP_MULTICAST_IF, getsockopt(2)
            // always returns an in_addr.
            sockaddr_storage ss;
            memset(&ss, 0, sizeof(ss));
            ss.ss_family = AF_INET; // This call is IPv4-only.
            sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(&ss);
            if (!getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &sa->sin_addr)) {
                return NULL;
            }
            return socketAddressToInetAddress(env, &ss);
        }
    case JAVASOCKOPT_IP_MULTICAST_IF2:
        if (family == AF_INET) {
            // The caller's asking for an interface index, but that's not how IPv4 works.
            // Our Java should never get here, because we'll try IP_MULTICAST_IF first and
            // that will satisfy us.
            jniThrowSocketException(env, EAFNOSUPPORT);
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF);
        }
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        if (family == AF_INET) {
            // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
            u_char loopback;
            bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback);
            return ok ? booleanValueOf(env, loopback) : NULL;
        } else {
            return getSocketOption_Boolean(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
        }
    case JAVASOCKOPT_MULTICAST_TTL:
        if (family == AF_INET) {
            // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int,
            // IPv4 multicast TTL uses a byte.
            u_char ttl;
            bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl);
            return ok ? integerValueOf(env, ttl) : NULL;
        } else {
            return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
        }
#else
    case JAVASOCKOPT_MULTICAST_TTL:
    case JAVASOCKOPT_IP_MULTICAST_IF:
    case JAVASOCKOPT_IP_MULTICAST_IF2:
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
        return NULL;
#endif // def ENABLE_MULTICAST
    default:
        jniThrowSocketException(env, ENOPROTOOPT);
        return NULL;
    }
}
예제 #4
0
static jobject getSocketOption_Integer(JNIEnv* env, const NetFd& fd, int level, int option) {
    int value;
    return getSocketOption(env, fd, level, option, &value) ? integerValueOf(env, value) : NULL;
}
예제 #5
0
DWORD Socket::getConnectionTime() {
	DWORD connectionTime;
	getSocketOption( SO_CONNECT_TIME, connectionTime );
	return connectionTime;
}
예제 #6
0
DWORD Socket::getInputTimeout()
{
	DWORD timeout;
	getSocketOption(SO_RCVTIMEO, timeout);
	return timeout;
}
예제 #7
0
bool Socket::isKeepAlive()
{
	DWORD keepAlive = 0;
	getSocketOption(SO_KEEPALIVE, keepAlive);
	return keepAlive != 0;
}
예제 #8
0
bool Socket::isRoutingEnabled()
{
	DWORD enabled;
	getSocketOption(SO_DONTROUTE, enabled);
	return enabled != 0;
}
예제 #9
0
USHORT Socket::getLingerTime()
{
	linger ln;
	getSocketOption(SO_LINGER, ln);
	return ln.l_linger;
}