test_ncbi_socket.c

来自「ncbi源码」· C语言 代码 · 共 1,021 行 · 第 1/3 页

C
1,021
字号
    EIO_Status status;    size_t     n_io, n_io_done, i;    char       buf[W_FIELD * N_FIELD + 1];    fprintf(log_fp, "[INFO] TEST__client_2(TC2)\n");    /* fill out a buffer to send to server */    memset(buf, 0, sizeof(buf));    for (i = 0;  i < N_FIELD;  i++) {        sprintf(buf + i * W_FIELD, "%10lu", (unsigned long)i);    }    /* send the buffer to server, then get it back */    for (i = 0;  i < N_REPEAT;  i++) {        char        buf1[sizeof(buf)];        STimeout    w_to, r_to;        int/*bool*/ w_timeout_on = (int)(i%2); /* if to start from     */        int/*bool*/ r_timeout_on = (int)(i%3); /* zero or inf. timeout */        char*       x_buf;        /* set timeout */        w_to.sec  = 0;        w_to.usec = 0;        status = SOCK_SetTimeout(sock, eIO_Write, w_timeout_on ? &w_to : 0);        assert(status == eIO_Success);#ifdef DO_RECONNECT        /* reconnect */        if ((i % N_RECONNECT) == 0) {            size_t j = i / N_RECONNECT;            do {                status = SOCK_Reconnect(sock, 0, 0, 0);                fprintf(log_fp,                        "[INFO] TEST__client_2::reconnect: i=%lu, status=%s\n",                        (unsigned long)i, IO_StatusStr(status));                assert(status == eIO_Success);                assert(SOCK_Status(sock, eIO_Read)  == eIO_Success);                assert(SOCK_Status(sock, eIO_Write) == eIO_Success);                /* give a break to let server reset the listening socket */                X_SLEEP(1);            } while ( j-- );        }#endif        /* send */        x_buf = buf;        n_io = sizeof(buf);        do {            X_SLEEP(1);            status = SOCK_Write(sock, x_buf, n_io,                                &n_io_done, eIO_WritePersist);            if (status == eIO_Closed) {                fprintf(log_fp,                        "[ERROR] TC2::write: connection closed\n");                assert(0);            }            fprintf(log_fp, "[INFO] TC2::write "                    "i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu"                    "\ntimeout(%d): %5lu sec, %6lu msec\n",                    (int)i, IO_StatusStr(status),                    (unsigned long)n_io, (unsigned long)n_io_done,                    (int)w_timeout_on,                    (unsigned long)w_to.sec, (unsigned long)w_to.usec);            if ( !w_timeout_on ) {                assert(status == eIO_Success  &&  n_io_done == n_io);            } else {                const STimeout* x_to;                assert(status == eIO_Success  ||  status == eIO_Timeout);                x_to = SOCK_GetTimeout(sock, eIO_Write);                assert(w_to.sec == x_to->sec  &&  w_to.usec == x_to->usec);            }            n_io  -= n_io_done;            x_buf += n_io_done;            if (status == eIO_Timeout)                s_DoubleTimeout(&w_to);            status = SOCK_SetTimeout(sock, eIO_Write, &w_to);            assert(status == eIO_Success);            w_timeout_on = 1/*true*/;        } while ( n_io );        /* get back the just sent data */        r_to.sec  = 0;        r_to.usec = 0;        status = SOCK_SetTimeout(sock, eIO_Read, (r_timeout_on ? &r_to : 0));        assert(status == eIO_Success);        x_buf = buf1;        n_io = sizeof(buf1);        do {            if (i%2 == 0) {                /* peek a little piece twice and compare */                char   xx_buf1[128], xx_buf2[128];                size_t xx_io_done1, xx_io_done2;                if (SOCK_Read(sock, xx_buf1, sizeof(xx_buf1), &xx_io_done1,                              eIO_ReadPeek) == eIO_Success  &&                    SOCK_Read(sock, xx_buf2, xx_io_done1, &xx_io_done2,                              eIO_ReadPeek) == eIO_Success) {                    assert(xx_io_done1 >= xx_io_done2);                    assert(memcmp(xx_buf1, xx_buf2, xx_io_done2) == 0);                }            }            status = SOCK_Read(sock, x_buf, n_io, &n_io_done, eIO_ReadPlain);            if (status == eIO_Closed) {                fprintf(log_fp,                        "[ERROR] TC2::read: connection closed\n");                assert(SOCK_Status(sock, eIO_Read) == eIO_Closed);                assert(0);            }            fprintf(log_fp, "[INFO] TC2::read: "                    "i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu"                    "\ntimeout(%d): %5u sec, %6u usec\n",                    (int)i, IO_StatusStr(status),                    (unsigned long)n_io, (unsigned long)n_io_done,                    (int)r_timeout_on, r_to.sec, r_to.usec);            if ( !r_timeout_on ) {                assert(status == eIO_Success  &&  n_io_done > 0);            } else {                const STimeout* x_to;                assert(status == eIO_Success  ||  status == eIO_Timeout);                x_to = SOCK_GetTimeout(sock, eIO_Read);                assert(r_to.sec == x_to->sec  &&  r_to.usec == x_to->usec);            }            n_io  -= n_io_done;            x_buf += n_io_done;            if (status == eIO_Timeout)                s_DoubleTimeout(&r_to);            status = SOCK_SetTimeout(sock, eIO_Read, &r_to);            assert(status == eIO_Success);            r_timeout_on = 1/*true*/;        } while ( n_io );        assert(memcmp(buf, buf1, sizeof(buf)) == 0);    }}static void TEST__server_2(SOCK sock, LSOCK lsock){    EIO_Status status;    size_t     n_io, n_io_done;    char       buf[TEST_BUFSIZE];    STimeout   r_to, w_to, rc_to;    size_t     i;    fprintf(log_fp, "[INFO] TEST__server_2(TS2)\n");    r_to.sec   = 0;    r_to.usec  = 0;    w_to = r_to;    rc_to.sec  = 30;    rc_to.usec = 123456;    /* goto */ l_reconnect: /* reconnection loopback */    status = SOCK_SetTimeout(sock, eIO_Read,  &r_to);    assert(status == eIO_Success);    status = SOCK_SetTimeout(sock, eIO_Write, &w_to);    assert(status == eIO_Success);    for (i = 0;  ;  i++) {        char* x_buf;        /* read data from socket */        n_io = sizeof(buf);        status = SOCK_Read(sock, buf, n_io, &n_io_done, eIO_ReadPlain);        switch ( status ) {        case eIO_Success:            fprintf(log_fp, "[INFO] TS2::read: "                    "[%lu], status=%7s, n_io=%5lu, n_io_done=%5lu\n",                    (unsigned long)i, IO_StatusStr(status),                    (unsigned long)n_io, (unsigned long)n_io_done);            assert(n_io_done > 0);            break;        case eIO_Closed:            fprintf(log_fp, "[INFO] TS2::read: connection closed\n");            assert(SOCK_Status(sock, eIO_Read) == eIO_Closed);            /* reconnect */            if ( !lsock )                return;            fprintf(log_fp, "[INFO] TS2:: reconnect\n");            SOCK_Close(sock);            if ((status = LSOCK_Accept(lsock, &rc_to, &sock)) != eIO_Success)                return;            assert(SOCK_Status(sock, eIO_Read) == eIO_Success);            /* !!! */            goto l_reconnect;        case eIO_Timeout:            fprintf(log_fp, "[INFO] TS2::read: "                    "[%lu] timeout expired: %5u sec, %6u usec\n",                    (unsigned long)i, r_to.sec, r_to.usec);            assert(n_io_done == 0);            s_DoubleTimeout(&r_to);            status = SOCK_SetTimeout(sock, eIO_Read, &r_to);            assert(status == eIO_Success);            assert(SOCK_Status(sock, eIO_Read) == eIO_Success);            break;        default:            assert(0);            return;        } /* switch */        /* write(just the same) data back to client */        n_io  = n_io_done;        x_buf = buf;        while ( n_io ) {            status = SOCK_Write(sock, buf, n_io, &n_io_done, eIO_WritePersist);            switch ( status ) {            case eIO_Success:                fprintf(log_fp, "[INFO] TS2::write: "                        "[%lu], status=%7s, n_io=%5lu, n_io_done=%5lu\n",                        (unsigned long)i, IO_StatusStr(status),                        (unsigned long)n_io, (unsigned long)n_io_done);                assert(n_io_done > 0);                break;            case eIO_Closed:                fprintf(log_fp, "[ERROR] TS2::write: connection closed\n");                assert(0);                return;            case eIO_Timeout:                fprintf(log_fp, "[INFO] TS2::write: "                        "[%lu] timeout expired: %5u sec, %6u usec\n",                        (unsigned long)i, w_to.sec, w_to.usec);                assert(n_io_done == 0);                s_DoubleTimeout(&w_to);                status = SOCK_SetTimeout(sock, eIO_Write, &w_to);                assert(status == eIO_Success);                break;            default:                assert(0);                return;            } /* switch */            n_io  -= n_io_done;            x_buf += n_io_done;        }    }}/* Skeletons for the socket i/o test: *   TEST__client(...) *   TEST__server(...) *   establish and close connection;  call test i/o functions like *     TEST__[client|server]_[1|2|...] (...) */static void TEST__client(const char*     server_host,                         unsigned short  server_port,                         const STimeout* timeout){    SOCK       sock;    EIO_Status status;    fprintf(log_fp, "[INFO] TEST__client(host = \"%s\", port = %hu, ",            server_host, server_port);    if ( timeout )        fprintf(log_fp, "timeout = %u.%u)\n", timeout->sec, timeout->usec);    else        fprintf(log_fp, "timeout = INFINITE)\n");    /* Connect to server */    status = SOCK_Create(server_host, server_port, timeout, &sock);    assert(status == eIO_Success);    /* Test the simplest randezvous(plain request-reply)     * The two peer functions are:     *      "TEST__[client|server]_1(SOCK sock)"     */    TEST__client_1(sock);    /* Test a more complex case     * The two peer functions are:     *      "TEST__[client|server]_2(SOCK sock)"     */    TEST__client_2(sock);    /* Close connection and exit */    status = SOCK_Close(sock);    assert(status == eIO_Success  ||  status == eIO_Closed);}static void TEST__server(unsigned short port){    LSOCK      lsock;    EIO_Status status;    fprintf(log_fp, "[INFO] TEST__server(port = %hu)\n", port);    /* Create listening socket */    status = LSOCK_Create(port, 1, &lsock);    assert(status == eIO_Success);    /* Accept connections from clients and run test sessions */    for (;;) {        /* Accept connection */        SOCK sock;        status = LSOCK_Accept(lsock, NULL, &sock);        assert(status == eIO_Success);        /* Test the simplest randezvous(plain request-reply)         * The two peer functions are:         *      "TEST__[client|server]_1(SOCK sock)"         */        TEST__server_1(sock);        /* Test a more complex case         * The two peer functions are:         *      "TEST__[client|server]_2(SOCK sock)"         */#ifdef DO_RECONNECT        TEST__server_2(sock, lsock);#else        TEST__server_2(sock, 0);#endif        /* Close connection */        status = SOCK_Close(sock);        assert(status == eIO_Success  ||  status == eIO_Closed);#ifdef TEST_SRV1_ONCE        /* Close listening socket */        assert(LSOCK_Close(lsock) == eIO_Success);        /* Finish after the first session */        break;#endif    } /* for */}/* Consistency... */#if defined(DO_SERVER)  &&  defined(DO_CLIENT)#  error "Only one of DO_SERVER, DO_CLIENT can be defined!"

⌨️ 快捷键说明

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