⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:

    TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p);
    if (s->net->type == TCN_SOCKET_APR) {
        TCN_ASSERT(s->sock != NULL);
        TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (n) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&sp_accepted);
#endif
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        a->sock   = n;
        a->pool   = p;
        a->net    = &apr_socket_layer;
        a->opaque = n;
        apr_pool_cleanup_register(p, (const void *)a,
                                  sp_socket_cleanup,
                                  apr_pool_cleanup_null);
    }
    return P2J(a);
cleanup:
    if (p)
        apr_pool_destroy(p);
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Socket, connect)(TCN_STDARGS, jlong sock,
                                          jlong sa)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    return (jint)apr_socket_connect(s->sock, a);
}

TCN_IMPLEMENT_CALL(jint, Socket, send)(TCN_STDARGS, jlong sock,
                                      jbyteArray buf, jint offset, jint tosend)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)tosend;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    if (tosend <= TCN_BUFFER_SZ) {
        char sb[TCN_BUFFER_SZ];
        (*e)->GetByteArrayRegion(e, buf, offset, tosend, (jbyte *)sb);
        ss = (*s->net->send)(s->opaque, sb, &nbytes);
    }
    else {
        jbyte *bytes;
        apr_int32_t nb;
        apr_socket_opt_get(s->sock, APR_SO_NONBLOCK, &nb);
        if (nb)
            bytes = (*e)->GetPrimitiveArrayCritical(e, buf, NULL);
        else
            bytes = (*e)->GetByteArrayElements(e, buf, NULL);
        ss = (*s->net->send)(s->opaque, (char *)(bytes + offset), &nbytes);
        if (nb)
            (*e)->ReleasePrimitiveArrayCritical(e, buf, bytes, JNI_ABORT);
        else
            (*e)->ReleaseByteArrayElements(e, buf, bytes, JNI_ABORT);
    }
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(void, Socket, setsbb)(TCN_STDARGS, jlong sock,
                                         jobject buf)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    if (buf)
        s->jsbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
    else
        s->jsbbuff = NULL;
}

TCN_IMPLEMENT_CALL(void, Socket, setrbb)(TCN_STDARGS, jlong sock,
                                         jobject buf)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    if (buf)
        s->jrbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
    else
        s->jrbbuff = NULL;
}

TCN_IMPLEMENT_CALL(jint, Socket, sendb)(TCN_STDARGS, jlong sock,
                                        jobject buf, jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)len;
    apr_size_t sent = 0;
    char *bytes;
    apr_status_t ss = APR_SUCCESS;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);

    while (sent < nbytes) {
        apr_size_t wr = nbytes - sent;
        ss = (*s->net->send)(s->opaque, bytes + offset + sent, &wr);
        if (ss != APR_SUCCESS)
            break;
        sent += wr;
    }

    if (ss == APR_SUCCESS)
        return (jint)sent;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendbb)(TCN_STDARGS, jlong sock,
                                         jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)len;
    apr_size_t sent = 0;
    apr_status_t ss = APR_SUCCESS;

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(s->jsbbuff != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    while (sent < nbytes) {
        apr_size_t wr = nbytes - sent;
        ss = (*s->net->send)(s->opaque, s->jsbbuff + offset + sent, &wr);
        if (ss != APR_SUCCESS)
            break;
        sent += wr;
    }
    if (ss == APR_SUCCESS)
        return (jint)sent;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendv)(TCN_STDARGS, jlong sock,
                                        jobjectArray bufs)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    jsize nvec;
    jsize i;
    struct iovec vec[APR_MAX_IOVEC_SIZE];
    jobject ba[APR_MAX_IOVEC_SIZE];
    apr_size_t written = 0;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);

    nvec = (*e)->GetArrayLength(e, bufs);
    if (nvec >= APR_MAX_IOVEC_SIZE)
        return (jint)(-APR_ENOMEM);

    for (i = 0; i < nvec; i++) {
        ba[i] = (*e)->GetObjectArrayElement(e, bufs, i);
        vec[i].iov_len  = (*e)->GetArrayLength(e, ba[i]);
        vec[i].iov_base = (*e)->GetByteArrayElements(e, ba[i], NULL);
    }

    ss = (*s->net->sendv)(s->opaque, vec, nvec, &written);

    for (i = 0; i < nvec; i++) {
        (*e)->ReleaseByteArrayElements(e, ba[i], vec[i].iov_base, JNI_ABORT);
    }
    if (ss == APR_SUCCESS)
        return (jint)written;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, sendto)(TCN_STDARGS, jlong sock,
                                         jlong where, jint flag,
                                         jbyteArray buf, jint offset, jint tosend)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *w = J2P(where, apr_sockaddr_t *);
    apr_size_t nbytes = (apr_size_t)tosend;
    jbyte *bytes;
    apr_int32_t nb;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);

    bytes = (*e)->GetByteArrayElements(e, buf, NULL);
    TCN_ASSERT(bytes != NULL);
    apr_socket_opt_get(s->sock, APR_SO_NONBLOCK, &nb);
    if (nb)
         bytes = (*e)->GetPrimitiveArrayCritical(e, buf, NULL);
    else
         bytes = (*e)->GetByteArrayElements(e, buf, NULL);
    ss = apr_socket_sendto(s->sock, w, flag, (char *)(bytes + offset), &nbytes);

    if (nb)
        (*e)->ReleasePrimitiveArrayCritical(e, buf, bytes, 0);
    else
        (*e)->ReleaseByteArrayElements(e, buf, bytes, JNI_ABORT);
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recv)(TCN_STDARGS, jlong sock,
                                       jbyteArray buf, jint offset, jint toread)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)toread;
    apr_status_t ss;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);

    if (toread <= TCN_BUFFER_SZ) {
        char sb[TCN_BUFFER_SZ];

        if ((ss = (*s->net->recv)(s->opaque, sb, &nbytes)) == APR_SUCCESS)
            (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, (jbyte*)&sb[0]);
    }
    else {
        jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
        ss = (*s->net->recv)(s->opaque, (char*)(bytes + offset), &nbytes);
        (*e)->ReleaseByteArrayElements(e, buf, bytes,
                                       nbytes ? 0 : JNI_ABORT);
    }
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvt)(TCN_STDARGS, jlong sock,
                                        jbyteArray buf, jint offset,
                                        jint toread, jlong timeout)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)toread;
    apr_status_t ss;
    apr_interval_time_t t;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);

    if ((ss = (*s->net->timeout_get)(s->opaque, &t)) != APR_SUCCESS)
        goto cleanup;
    if ((ss = (*s->net->timeout_set)(s->opaque, J2T(timeout))) != APR_SUCCESS)
        goto cleanup;
    if (toread <= TCN_BUFFER_SZ) {
        char sb[TCN_BUFFER_SZ];
        ss = (*s->net->recv)(s->opaque, sb, &nbytes);
        (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, (jbyte*)&sb[0]);
    }
    else {
        jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
        ss = (*s->net->recv)(s->opaque, (char*)(bytes + offset), &nbytes);
        (*e)->ReleaseByteArrayElements(e, buf, bytes,
                                       nbytes ? 0 : JNI_ABORT);
    }
    /* Resore the original timeout */
    (*s->net->timeout_set)(s->opaque, t);
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
cleanup:
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvb)(TCN_STDARGS, jlong sock,
                                        jobject buf, jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;
    char *bytes;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(buf != NULL);

    bytes  = (char *)(*e)->GetDirectBufferAddress(e, buf);
    TCN_ASSERT(bytes != NULL);
    ss = (*s->net->recv)(s->opaque, bytes + offset, &nbytes);
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }
#endif
    if (ss == APR_SUCCESS)
        return (jint)nbytes;
    else {
        TCN_ERROR_WRAP(ss);
        return -(jint)ss;
    }
}

TCN_IMPLEMENT_CALL(jint, Socket, recvbb)(TCN_STDARGS, jlong sock,
                                         jint offset, jint len)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_status_t ss;
    apr_size_t nbytes = (apr_size_t)len;

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->opaque != NULL);
    TCN_ASSERT(s->jrbbuff != NULL);

    ss = (*s->net->recv)(s->opaque, s->jrbbuff + offset, &nbytes);
#ifdef TCN_DO_STATISTICS
    if (ss == APR_SUCCESS) {
        sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
        sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
        sp_tot_recv += nbytes;
        sp_num_recv++;
    }
    else {
        if (APR_STATUS_IS_ETIMEDOUT(ss) ||
            APR_STATUS_IS_TIMEUP(ss))
            sp_tmo_recv++;
        else if (APR_STATUS_IS_ECONNABORTED(ss) ||
                 APR_STATUS_IS_ECONNRESET(ss) ||
                 APR_STATUS_IS_EOF(ss))
            sp_rst_recv++;
        else {
            sp_err_recv++;
            sp_erl_recv = ss;
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -