mfc 关闭阻塞的socket监听线程 select怎么用

 我来答
小黑羊LBS
2017-01-06 · 超过53用户采纳过TA的回答
知道小有建树答主
回答量:107
采纳率:0%
帮助的人:55.2万
展开全部

首先,如果使用select函数来做网络通讯,即使不用多线程也是没有问题的。

如果说你在关闭监听线程,我暂且理解你想要结束服务了,那么:

1。在合适的地方,将socket关闭。

2。select函数本身没有什么释放的必要,之要在监听线程做好各项释放工作。

3。监听线程返回一个合适的状态码。

我上一个我自己写的,比较简单,应该很好理解:


typedef struct _lbs_socket_object_st  lbs_netlib_object_t;
struct _lbs_socket_object_st {
    /* Real socket of the object */
    SOCKET sock;
    struct sockaddr_in addr;
    struct sockaddr_in udp_addr;
    HANDLE worker;

    /* Flag shows that if this object is a server or client */
    lbs_bool_t is_server;
    lbs_bool_t is_udp;

    /* Socket type: STREAM or DGRAM */
    int type;

    /* Working method flag */
    int flag;

    /*
     * Server Mode: True if server is started.
     * Client Mode: True if client has connected to server.
     */
    int actived;

    /* Fields below are used for server */
    int threads_expension_type; // Method for thread pool
    int threads_cnt; // Count of threads in threads pool
    int clients_cnt; // Count of clients who are connected
    lbs_sock_node_t* client_head;

    /* Only server will use a thread pool */
    lbs_thread_pool_handle_t threadpool;

    /* Callback functions */
    read_callback  read_cb;
    error_callback error_cb;

    int error;

    lbs_socket_object_t* next;
    lbs_socket_object_t* prev;
};
unsigned long _stdcall lbs_netlib_server_listen_thread(void* param)
{
    lbs_netlib_object_t* server = (lbs_netlib_object_t*)param;
    FD_SET listen_fdset;
    FD_SET temp_fdset;
    struct timeval tv = {5, 100};
    int rc;

    /* Check for parameters*/
    if (server == 0) {
        /* @@@ We can not pass this error to anywhere.
         * @@@ Maybe we can write it into log in the future.
         */
        return 1;
    }

    /* Do some initializations */
    FD_ZERO(&listen_fdset);
    FD_ZERO(&temp_fdset);
    FD_SET(server->sock, &listen_fdset);

    /* Process loop */
    while (1) {
        int event_cnt; // Event counts set by 'select'

        temp_fdset = listen_fdset;

        /* whether caller wants to stop server */
        if (server->actived == 0) {
            goto clean_up;
        }
    
        /* Detect events */
        event_cnt = select(0, &temp_fdset, 0, 0, &tv);
        if (event_cnt == 0) continue;
        if (FD_ISSET(server->sock, &temp_fdset)) {
            int size;
            lbs_sock_node_t* client;

            client= lbs_netlib_new_client_node();

            if (client == 0) {
                /* @@@ There is not memory. We should log error here */
                continue;
            }

            size = sizeof(struct sockaddr_in);
            client->sock = accept(server->sock, (struct sockaddr*)&(client->addr), &size);
            if (client->sock == -1){
                /* @@@ Socket cannot be created. Maybe system does not
                * have such resources. We should log error here.
                */
                rc = GetLastError();
                lbs_rwlock_unlock(server->obj_lock);
                lbs_netlib_destroy_client_node(client, 0);
            } else {
                lbs_rwlock_unlock(server->obj_lock);
                if (!lbs_threadpool_push_task(server->threadpool, client, 0)) {
                    server->clients_cnt++;
                    if (server->error_cb) {
                        server->error_cb((lbs_netlib_client_t)client, 0);
                    }
                }
            } // Exit of accept result checking
        } // Exit of select result checking
    } // Exit of loop

clean_up:

    return LBS_NETLIB_OK;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式