示例#1
0
文件: aiop.c 项目: cdrr/tbox
tb_void_t tb_aiop_exit(tb_aiop_ref_t aiop)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return(impl);

    // exit reactor
    if (impl->rtor && impl->rtor->exit)
        impl->rtor->exit(impl->rtor);

    // exit spak
    if (impl->spak[0]) tb_socket_exit(impl->spak[0]);
    if (impl->spak[1]) tb_socket_exit(impl->spak[1]);
    impl->spak[0] = tb_null;
    impl->spak[1] = tb_null;

    // exit pool
    tb_spinlock_enter(&impl->lock);
    if (impl->pool) tb_fixed_pool_exit(impl->pool);
    impl->pool = tb_null;
    tb_spinlock_leave(&impl->lock);

    // exit lock
    tb_spinlock_exit(&impl->lock);

    // free impl
    tb_free(impl);
}
示例#2
0
tb_void_t tb_poller_exit(tb_poller_ref_t self)
{
    // check
    tb_poller_poll_ref_t poller = (tb_poller_poll_ref_t)self;
    tb_assert_and_check_return(poller);

    // exit pair sockets
    if (poller->pair[0]) tb_socket_exit(poller->pair[0]);
    if (poller->pair[1]) tb_socket_exit(poller->pair[1]);
    poller->pair[0] = tb_null;
    poller->pair[1] = tb_null;

    // exit hash
    if (poller->hash) tb_free(poller->hash);
    poller->hash        = tb_null;
    poller->hash_size   = 0;

    // close pfds
    if (poller->pfds) tb_vector_exit(poller->pfds);
    poller->pfds = tb_null;

    // close cfds
    if (poller->cfds) tb_vector_exit(poller->cfds);
    poller->cfds = tb_null;

    // free it
    tb_free(poller);
}
示例#3
0
static tb_void_t tb_demo_http_session_exit(tb_demo_http_session_ref_t session)
{
    // check
    tb_assert(session);

    // exit socket
    if (session->sock) tb_socket_exit(session->sock);
    session->sock = tb_null;

    // exit file
    if (session->file) tb_file_exit(session->file);
    session->file = tb_null;
}
示例#4
0
文件: looker.c 项目: waruqi/tbox
tb_void_t tb_dns_looker_exit(tb_dns_looker_ref_t self)
{
    // the looker
    tb_dns_looker_t* looker = (tb_dns_looker_t*)self;
    if (looker)
    {
        // exit sock
        if (looker->sock) tb_socket_exit(looker->sock);
        looker->sock = tb_null;

        // exit it
        tb_free(looker);
    }
}
示例#5
0
文件: looker.c 项目: luxuan/tbox
tb_void_t tb_dns_looker_exit(tb_dns_looker_ref_t looker)
{
    // the impl
    tb_dns_looker_impl_t* impl = (tb_dns_looker_impl_t*)looker;
    if (impl)
    {
        // exit sock
        if (impl->sock) tb_socket_exit(impl->sock);
        impl->sock = tb_null;

        // exit it
        tb_free(impl);
    }
}
示例#6
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * main
 */ 
tb_int_t tb_demo_coroutine_http_server_main(tb_int_t argc, tb_char_t** argv)
{
    // done
    tb_socket_ref_t sock = tb_null;
    do
    {
        // init socket
        sock = tb_socket_init(TB_SOCKET_TYPE_TCP, TB_IPADDR_FAMILY_IPV4);
        tb_assert_and_check_break(sock);

        // bind socket
        tb_ipaddr_t addr;
        tb_ipaddr_set(&addr, tb_null, TB_DEMO_PORT, TB_IPADDR_FAMILY_IPV4);
        if (!tb_socket_bind(sock, &addr)) break;

        // listen socket
        if (!tb_socket_listen(sock, 1000)) break;

        // init the root directory
        if (argv[1]) tb_strlcpy(g_rootdir, argv[1], sizeof(g_rootdir));
        else tb_directory_current(g_rootdir, sizeof(g_rootdir));

        // only data?
        if (!tb_file_info(g_rootdir, tb_null)) g_onlydata = tb_true;

        // trace
        tb_trace_i("%s: %s", g_onlydata? "data" : "rootdir", g_rootdir);

#if TB_DEMO_CPU > 1
        // start workers for multi-threads
        tb_size_t count = TB_DEMO_CPU - 1;
        while (count--) tb_thread_init(tb_null, tb_demo_coroutine_worker, sock, 0);
#endif

        // start worker
        tb_demo_coroutine_worker(sock);

    } while (0);

    // exit socket
    if (sock) tb_socket_exit(sock);
    sock = tb_null;

    // ok
    return 0;
}
示例#7
0
文件: aico.c 项目: 1060460048/tbox
tb_bool_t tb_aico_open_sock_from_type(tb_aico_ref_t aico, tb_size_t type)
{
    // check
    tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
    tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
    tb_assert_and_check_return_val(impl && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);

    // done
    tb_bool_t       ok = tb_false;
    tb_socket_ref_t sock = tb_null;
    do
    {
        // closed?
        tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
        tb_assert_and_check_break(!impl->type && !impl->handle);

        // init sock
        sock = tb_socket_init(type);
        tb_assert_and_check_break(sock);

        // bind type and handle
        impl->type     = TB_AICO_TYPE_SOCK;
        impl->handle   = (tb_handle_t)sock;

        // addo aico
        ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
        tb_assert_and_check_break(ok);

        // opened
        tb_atomic_set(&impl->state, TB_STATE_OPENED);

    } while (0);

    // failed?
    if (!ok)
    {
        // exit it
        if (sock) tb_socket_exit(sock);
        sock = tb_null;
    }

    // ok?
    return ok;
}
示例#8
0
文件: aiopd.c 项目: 1060460048/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_void_t tb_demo_context_exit(tb_aiop_ref_t aiop, tb_demo_context_t* context)
{
    if (context)
    {
        // exit aioo
        if (context->aioo) tb_aiop_delo(aiop, context->aioo);
        context->aioo = tb_null;

        // exit sock
        if (context->sock) tb_socket_exit(context->sock);
        context->sock = tb_null;

        // exit file
        if (context->file) tb_file_exit(context->file);
        context->file = tb_null;

        // exit data
        if (context->data) tb_free(context->data);
        context->data = tb_null;

        // exit it
        tb_free(context);
    }
}
示例#9
0
文件: aiopd.c 项目: 1060460048/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * main
 */
tb_int_t tb_demo_asio_aiopd_main(tb_int_t argc, tb_char_t** argv)
{
    // check
    tb_assert_and_check_return_val(argv[1], 0);

    // done
    tb_socket_ref_t sock = tb_null;
    tb_aiop_ref_t   aiop = tb_null;
    do
    {
        // init sock
        sock = tb_socket_init(TB_SOCKET_TYPE_TCP);
        tb_assert_and_check_break(sock);

        // init aiop
        aiop = tb_aiop_init(16);
        tb_assert_and_check_break(aiop);

        // bind 
        if (!tb_socket_bind(sock, tb_null, 9090)) break;

        // listen sock
        if (!tb_socket_listen(sock, 20)) break;

        // addo sock
        if (!tb_aiop_addo(aiop, sock, TB_AIOE_CODE_ACPT, tb_null)) break;

        // accept
        tb_aioe_t list[16];
        while (1)
        {
            // wait
            tb_long_t objn = tb_aiop_wait(aiop, list, 16, -1);
            tb_assert_and_check_break(objn >= 0);

            // walk list
            tb_size_t i = 0;
            for (i = 0; i < objn; i++)
            {
                // the aioo 
                tb_aioo_ref_t aioo = list[i].aioo;

                // check
                tb_assert_and_check_break(aioo && tb_aioo_sock(aioo));

                // acpt?
                if (list[i].code & TB_AIOE_CODE_ACPT)
                {
                    // done acpt
                    tb_bool_t           ok = tb_false;
                    tb_demo_context_t*  context = tb_null;
                    do
                    {
                        // make context
                        context = tb_malloc0_type(tb_demo_context_t);
                        tb_assert_and_check_break(context);

                        // init sock
                        context->sock = tb_socket_accept(tb_aioo_sock(aioo), tb_null, tb_null);
                        tb_assert_and_check_break(context->sock);

                        // init file
                        context->file = tb_file_init(argv[1], TB_FILE_MODE_RO);
                        tb_assert_and_check_break(context->file);

                        // init data
                        context->data = tb_malloc_bytes(TB_DEMO_FILE_READ_MAXN);
                        tb_assert_and_check_break(context->data);

                        // addo sock
                        context->aioo = tb_aiop_addo(aiop, context->sock, TB_AIOE_CODE_SEND, context);
                        tb_assert_and_check_break(context->aioo);

                        // trace
                        tb_trace_i("acpt[%p]: ok", context->sock);

                        // init left
                        context->left = tb_file_size(context->file);

                        // done read
                        tb_long_t real = tb_file_read(context->file, context->data, tb_min((tb_size_t)context->left, TB_DEMO_FILE_READ_MAXN));
                        tb_assert_and_check_break(real > 0);

                        // save size
                        context->left -= real;

                        // trace
    //                  tb_trace_i("read[%p]: real: %ld", context->file, real);

                        // done send
                        context->send = real;
                        real = tb_socket_send(context->sock, context->data + context->real, context->send - context->real);
                        if (real >= 0)
                        {
                            // save real
                            context->real += real;

                            // trace
    //                      tb_trace_i("send[%p]: real: %ld", context->sock, real);
                        }
                        else
                        {
                            // trace
                            tb_trace_i("send[%p]: closed", context->sock);
                            break;
                        }

                        // ok
                        ok = tb_true;

                    } while (0);

                    // failed or closed?
                    if (!ok)
                    {
                        // exit context
                        tb_demo_context_exit(aiop, context);
                        break;
                    }
                }
                // writ?
                else if (list[i].code & TB_AIOE_CODE_SEND)
                {
                    // the context
                    tb_demo_context_t* context = (tb_demo_context_t*)list[i].priv;
                    tb_assert_and_check_break(context);

                    // continue to send it if not finished
                    if (context->real < context->send)
                    {
                        // done send
                        tb_long_t real = tb_socket_send(tb_aioo_sock(aioo), context->data + context->real, context->send - context->real);
                        if (real > 0)
                        {
                            // save real
                            context->real += real;

                            // trace
    //                      tb_trace_i("send[%p]: real: %ld", tb_aioo_sock(aioo), real);
                        }
                        else
                        {
                            // trace
                            tb_trace_i("send[%p]: closed", tb_aioo_sock(aioo));

                            // exit context
                            tb_demo_context_exit(aiop, context);
                            break;
                        }
                    }
                    // finished? read file
                    else if (context->left)
                    {
                        // init
                        context->real = 0;
                        context->send = 0;

                        // done read
                        tb_size_t tryn = 1;
                        tb_long_t real = 0;
                        while (!(real = tb_file_read(context->file, context->data, tb_min((tb_size_t)context->left, TB_DEMO_FILE_READ_MAXN))) && tryn--);
                        if (real > 0)
                        {
                            // save left
                            context->left -= real;

                            // trace
    //                      tb_trace_i("read[%p]: real: %ld", context->file, real);

                            // done send
                            context->send = real;
                            real = tb_socket_send(tb_aioo_sock(aioo), context->data, context->send);
                            if (real >= 0)
                            {
                                // save real
                                context->real += real;

                                // trace
    //                          tb_trace_i("send[%p]: real: %ld", tb_aioo_sock(aioo), real);
                            }
                            else
                            {
                                // trace
                                tb_trace_i("send[%p]: closed", tb_aioo_sock(aioo));

                                // exit context
                                tb_demo_context_exit(aiop, context);
                                break;
                            }
                        }
                        else
                        {
                            // trace
                            tb_trace_i("read[%p]: closed", tb_aioo_sock(aioo));

                            // exit context
                            tb_demo_context_exit(aiop, context);
                            break;
                        }
                    }
                    else 
                    {
                        // trace
                        tb_trace_i("read[%p]: closed", tb_aioo_sock(aioo));

                        // exit context
                        tb_demo_context_exit(aiop, context);
                        break;
                    }
                }
                // error?
                else 
                {
                    tb_trace_i("aioe[%p]: unknown code: %lu", tb_aioo_sock(aioo), list[i].code);
                    break;
                }
            }
        }
    } while (0);

    // trace
    tb_trace_i("end");

    // exit socket
    if (sock) tb_socket_exit(sock);

    // exit aiop
    if (aiop) tb_aiop_exit(aiop);

    // end
    return 0;
}
示例#10
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */ 
static tb_void_t tb_demo_coroutine_pull(tb_cpointer_t priv)
{
    // done
    tb_socket_ref_t sock = tb_null;
    do
    {
        // init socket
        sock = tb_socket_init(TB_SOCKET_TYPE_TCP, TB_IPADDR_FAMILY_IPV4);
        tb_assert_and_check_break(sock);

        // init address
        tb_ipaddr_t addr;
        tb_ipaddr_set(&addr, "127.0.0.1", TB_DEMO_PORT, TB_IPADDR_FAMILY_IPV4);

        // trace
        tb_trace_d("[%p]: connecting %{ipaddr} ..", sock, &addr);

        // connect socket
        tb_long_t ok;
        while (!(ok = tb_socket_connect(sock, &addr))) 
        {
            // wait it
            if (tb_socket_wait(sock, TB_SOCKET_EVENT_CONN, TB_DEMO_TIMEOUT) <= 0) break;
        }

        // connect ok?
        tb_check_break(ok > 0);

        // trace
        tb_trace_d("[%p]: recving ..", sock);

        // recv data
        tb_byte_t data[8192];
        tb_hize_t recv = 0;
        tb_long_t wait = 0;
        tb_hong_t time = tb_mclock();
        while (1)
        {
            // read it
            tb_long_t real = tb_socket_recv(sock, data, sizeof(data));

            // trace
            tb_trace_d("[%p]: recv: %ld, total: %lu", sock, real, recv + (real > 0? real : 0));

            // has data?
            if (real > 0)
            {
                recv += real;
                wait = 0;
            }
            // no data? wait it
            else if (!real && !wait)
            {
                // wait it
                wait = tb_socket_wait(sock, TB_SOCKET_EVENT_RECV, TB_DEMO_TIMEOUT);
                tb_assert_and_check_break(wait >= 0);
            }
            // failed or end?
            else break;
        }

        // trace
        tb_trace_i("[%p]: recv %llu bytes %lld ms", sock, recv, tb_mclock() - time);

    } while (0);

    // exit socket
    if (sock) tb_socket_exit(sock);
    sock = tb_null;
}
示例#11
0
文件: aicp_aiop.c 项目: ZuckerB/tbox
static tb_bool_t tb_aiop_push_acpt(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && aice, tb_false);
    tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_ACPT, tb_false);

    // the aico
    tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
    tb_assert_and_check_return_val(aico && aico->base.handle, tb_false);

    // the priority
    tb_size_t priority = tb_aice_impl_priority(aice);
    tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);

    // init the acpt aice
    tb_aice_t acpt_aice = *aice;
    acpt_aice.state = TB_STATE_OK;

    // done
    tb_size_t       list_indx = 0;
    tb_size_t       list_size = 0;
    tb_socket_ref_t list_sock[2048];
    tb_ipaddr_t       list_addr[2048];
    tb_size_t       list_maxn = tb_arrayn(list_sock);
    tb_socket_ref_t acpt = (tb_socket_ref_t)aico->base.handle;
    tb_queue_ref_t  spak = impl->spak[priority];
    tb_socket_ref_t sock = tb_null;
    do
    {
        // accept it
        for (list_size = 0; list_size < list_maxn && (list_sock[list_size] = tb_socket_accept(acpt, list_addr + list_size)); list_size++) ;

        // enter
        tb_spinlock_enter(&impl->lock);

        // push some acpt aice
        for (list_indx = 0; list_indx < list_size && (sock = list_sock[list_indx]); list_indx++)
        {
            // init aico
            acpt_aice.u.acpt.aico = tb_aico_init(aico->base.aicp);

            // trace
            tb_trace_d("push: acpt[%p]: sock: %p, aico: %p", aico->base.handle, sock, acpt_aice.u.acpt.aico);

            // open aico and push the acpt aice if not full?
            if (    acpt_aice.u.acpt.aico
                    &&  tb_aico_open_sock(acpt_aice.u.acpt.aico, sock)
                    &&  !tb_queue_full(spak))
            {
                // save addr
                tb_ipaddr_copy(&acpt_aice.u.acpt.addr, list_addr + list_indx);

                // push to the spak queue
                tb_queue_put(spak, &acpt_aice);
            }
            else
            {
                // close the left sock
                tb_size_t i;
                for (i = list_indx; i < list_size; i++)
                {
                    // close it
                    if (list_sock[i]) tb_socket_exit(list_sock[i]);
                    list_sock[i] = tb_null;
                }

                // exit aico
                if (acpt_aice.u.acpt.aico) tb_aico_exit(acpt_aice.u.acpt.aico);
                acpt_aice.u.acpt.aico = tb_null;

                // trace
                tb_trace_e("push: acpt failed!");
                break;
            }
        }

        // leave
        tb_spinlock_leave(&impl->lock);

    } while (list_indx == list_maxn);

    // ok
    return tb_true;
}
示例#12
0
文件: aicp_aiop.c 项目: ZuckerB/tbox
static tb_long_t tb_aiop_spak_clos(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && impl->timer && aice, -1);
    tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_CLOS, -1);

    // the aico
    tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
    tb_assert_and_check_return_val(aico, -1);

    // trace
    tb_trace_d("clos: aico: %p, code: %u: %s", aico, aice->code, tb_state_cstr(tb_atomic_get(&aico->base.state)));

    // exit the timer task
    if (aico->task)
    {
        if (aico->bltimer) tb_ltimer_task_exit(impl->ltimer, aico->task);
        else tb_timer_task_exit(impl->timer, aico->task);
        aico->bltimer = 0;
    }
    aico->task = tb_null;

    // exit the sock
    if (aico->base.type == TB_AICO_TYPE_SOCK)
    {
        // remove aioo
        if (aico->aioo) tb_aiop_delo(impl->aiop, aico->aioo);
        aico->aioo = tb_null;

        // close the socket handle
        if (aico->base.handle) tb_socket_exit((tb_socket_ref_t)aico->base.handle);
        aico->base.handle = tb_null;
    }
    // exit file
    else if (aico->base.type == TB_AICO_TYPE_FILE)
    {
        // exit the file handle
        if (aico->base.handle) tb_file_exit((tb_file_ref_t)aico->base.handle);
        aico->base.handle = tb_null;
    }

    // clear waiting state
    aico->waiting = 0;
    aico->wait_ok = 0;
    aico->aice.code = TB_AICE_CODE_NONE;

    // clear type
    aico->base.type = TB_AICO_TYPE_NONE;

    // clear timeout
    tb_size_t i = 0;
    tb_size_t n = tb_arrayn(aico->base.timeout);
    for (i = 0; i < n; i++) aico->base.timeout[i] = -1;

    // closed
    tb_atomic_set(&aico->base.state, TB_STATE_CLOSED);

    // ok
    aice->state = TB_STATE_OK;
    return 1;
}
示例#13
0
文件: looker.c 项目: waruqi/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_long_t tb_dns_looker_reqt(tb_dns_looker_t* looker)
{
    // check
    tb_check_return_val(!(looker->step & TB_DNS_LOOKER_STEP_REQT), 1);
    
    // format it first if the request is null
    if (!tb_static_buffer_size(&looker->rpkt))
    {
        // check size
        tb_assert_and_check_return_val(!looker->size, -1);

        // format query
        tb_static_stream_t  stream;
        tb_byte_t           rpkt[TB_DNS_RPKT_MAXN];
        tb_size_t           size = 0;
        tb_byte_t*          p = tb_null;
        tb_static_stream_init(&stream, rpkt, TB_DNS_RPKT_MAXN);

        // identification number
        tb_static_stream_writ_u16_be(&stream, TB_DNS_HEADER_MAGIC);

        /* 0x2104: 0 0000 001 0000 0000
         *
         * tb_uint16_t qr     :1;       // query/response flag
         * tb_uint16_t opcode :4;       // purpose of message
         * tb_uint16_t aa     :1;       // authoritive answer
         * tb_uint16_t tc     :1;       // truncated message
         * tb_uint16_t rd     :1;       // recursion desired

         * tb_uint16_t ra     :1;       // recursion available
         * tb_uint16_t z      :1;       // its z! reserved
         * tb_uint16_t ad     :1;       // authenticated data
         * tb_uint16_t cd     :1;       // checking disabled
         * tb_uint16_t rcode  :4;       // response code
         *
         * this is a query 
         * this is a standard query 
         * not authoritive answer 
         * not truncated 
         * recursion desired
         *
         * recursion not available! hey we dont have it (lol)
         *
         */
#if 1
        tb_static_stream_writ_u16_be(&stream, 0x0100);
#else
        tb_static_stream_writ_u1(&stream, 0);          // this is a query
        tb_static_stream_writ_ubits32(&stream, 0, 4);  // this is a standard query
        tb_static_stream_writ_u1(&stream, 0);          // not authoritive answer
        tb_static_stream_writ_u1(&stream, 0);          // not truncated
        tb_static_stream_writ_u1(&stream, 1);          // recursion desired

        tb_static_stream_writ_u1(&stream, 0);          // recursion not available! hey we dont have it (lol)
        tb_static_stream_writ_u1(&stream, 0);
        tb_static_stream_writ_u1(&stream, 0);
        tb_static_stream_writ_u1(&stream, 0);
        tb_static_stream_writ_ubits32(&stream, 0, 4);
#endif

        /* we have only one question
         *
         * tb_uint16_t question;        // number of question entries
         * tb_uint16_t answer;          // number of answer entries
         * tb_uint16_t authority;       // number of authority entries
         * tb_uint16_t resource;        // number of resource entries
         *
         */
        tb_static_stream_writ_u16_be(&stream, 1); 
        tb_static_stream_writ_u16_be(&stream, 0);
        tb_static_stream_writ_u16_be(&stream, 0);
        tb_static_stream_writ_u16_be(&stream, 0);

        // set questions, see as tb_dns_question_t
        // name + question1 + question2 + ...
        tb_static_stream_writ_u8(&stream, '.');
        p = (tb_byte_t*)tb_static_stream_writ_cstr(&stream, tb_static_string_cstr(&looker->name));

        // only one question now.
        tb_static_stream_writ_u16_be(&stream, 1);      // we are requesting the ipv4 address
        tb_static_stream_writ_u16_be(&stream, 1);      // it's internet (lol)

        // encode dns name
        if (!p || !tb_dns_encode_name((tb_char_t*)p - 1)) return -1;

        // size
        size = tb_static_stream_offset(&stream);
        tb_assert_and_check_return_val(size, -1);

        // copy
        tb_static_buffer_memncpy(&looker->rpkt, rpkt, size);
    }

    // data && size
    tb_byte_t const*    data = tb_static_buffer_data(&looker->rpkt);
    tb_size_t           size = tb_static_buffer_size(&looker->rpkt);

    // check
    tb_assert_and_check_return_val(data && size && looker->size < size, -1);

    // try get addr from the dns list
    tb_ipaddr_ref_t addr = tb_null;
    if (looker->maxn && looker->itor && looker->itor <= looker->maxn)
        addr = &looker->list[looker->itor - 1];

    // check
    tb_assert_and_check_return_val(addr && !tb_ipaddr_is_empty(addr), -1);

    // family have been changed? reinit socket
    if (tb_ipaddr_family(addr) != looker->family)
    {
        // exit the previous socket
        if (looker->sock) tb_socket_exit(looker->sock);

        // init a new socket for the family
        looker->sock = tb_socket_init(TB_SOCKET_TYPE_UDP, tb_ipaddr_family(addr));
        tb_assert_and_check_return_val(looker->sock, -1);

        // update the new family
        looker->family = (tb_uint8_t)tb_ipaddr_family(addr);
    }

    // need wait if no data
    looker->step &= ~TB_DNS_LOOKER_STEP_NEVT;

    // trace
    tb_trace_d("request: try %{ipaddr}", addr);

    // send request
    while (looker->size < size)
    {
        // writ data
        tb_long_t writ = tb_socket_usend(looker->sock, addr, data + looker->size, size - looker->size);
        tb_assert_and_check_return_val(writ >= 0, -1);

        // no data? 
        if (!writ)
        {
            // abort?
            tb_check_return_val(!looker->size && !looker->tryn, -1);

            // tryn++
            looker->tryn++;

            // continue
            return 0;
        }
        else looker->tryn = 0;

        // update size
        looker->size += writ;
    }

    // finish it
    looker->step |= TB_DNS_LOOKER_STEP_REQT;
    looker->tryn = 0;

    // reset rpkt
    looker->size = 0;
    tb_static_buffer_clear(&looker->rpkt);

    // ok
    tb_trace_d("request: ok");
    return 1;
}
示例#14
0
文件: mswsock.c 项目: mzfhhhh/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_bool_t tb_mswsock_instance_init(tb_handle_t instance)
{
    // check
    tb_mswsock_ref_t mswsock = (tb_mswsock_ref_t)instance;
    tb_assert_and_check_return_val(mswsock, tb_false);

    // done
    tb_socket_ref_t sock = tb_null;
    do
    {
        // init sock
        sock = tb_socket_init(TB_SOCKET_TYPE_TCP);
        tb_assert_and_check_break(sock);

        // init AcceptEx
        DWORD   AcceptEx_real = 0;
        GUID    AcceptEx_guid = TB_MSWSOCK_WSAID_ACCEPTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &AcceptEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->AcceptEx
                                ,   sizeof(tb_mswsock_AcceptEx_t)
                                ,   &AcceptEx_real
                                ,   tb_null
                                ,   tb_null);

        // init ConnectEx
        DWORD   ConnectEx_real = 0;
        GUID    ConnectEx_guid = TB_MSWSOCK_WSAID_CONNECTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &ConnectEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->ConnectEx
                                ,   sizeof(tb_mswsock_ConnectEx_t)
                                ,   &ConnectEx_real
                                ,   tb_null
                                ,   tb_null);

        // init DisconnectEx
        DWORD   DisconnectEx_real = 0;
        GUID    DisconnectEx_guid = TB_MSWSOCK_WSAID_DISCONNECTEX;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &DisconnectEx_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->DisconnectEx
                                ,   sizeof(tb_mswsock_DisconnectEx_t)
                                ,   &DisconnectEx_real
                                ,   tb_null
                                ,   tb_null);

        // init TransmitFile
        DWORD   TransmitFile_real = 0;
        GUID    TransmitFile_guid = TB_MSWSOCK_WSAID_TRANSMITFILE;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &TransmitFile_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->TransmitFile
                                ,   sizeof(tb_mswsock_TransmitFile_t)
                                ,   &TransmitFile_real
                                ,   tb_null
                                ,   tb_null);

        // init GetAcceptExSockaddrs
        DWORD   GetAcceptExSockaddrs_real = 0;
        GUID    GetAcceptExSockaddrs_guid = TB_MSWSOCK_WSAID_GETACCEPTEXSOCKADDRS;
        tb_ws2_32()->WSAIoctl(  (SOCKET)sock - 1
                                ,   SIO_GET_EXTENSION_FUNCTION_POINTER
                                ,   &GetAcceptExSockaddrs_guid
                                ,   sizeof(GUID)
                                ,   &mswsock->GetAcceptExSockaddrs
                                ,   sizeof(tb_mswsock_GetAcceptExSockaddrs_t)
                                ,   &GetAcceptExSockaddrs_real
                                ,   tb_null
                                ,   tb_null);
    } while (0);

    // exit sock
    if (sock) tb_socket_exit(sock);

    // ok
    return tb_true;
}