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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mfc 关闭阻塞的socket监听线程 select怎么用相关的知识,希望对你有一定的参考价值。

参考技术A

首先,如果使用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;

MFC socket编程

一、基本概念

a) 同步:指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。

nb)异步:指的是发送方不等接收方响应,便接着发下个数据包的通信方式。

c) 阻塞:指调用某函数时,直到该函数完成操作,才返回;否则一直阻塞在该调用上。

d) 非阻塞:指调用某操作时,不管操作是否成功都立即返回,而不会挂在该操作上。

二、soeket简介

   Client/Server (客户机/服务器)模型为最常用的模型。在这种方案中客户应用程序向服务器程序请求服务,一个服务器程序通常用一个众所周知的地址监听对服务的请求,也就是说服务器进程一直处于休眠状态,直到一个客户向这个服务器的地址提出了连接请求。在这个时刻,服务程序被"惊醒"并且为客户提供服务,即对客户的请求作出适当的反应。

  Socket 实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有 Socket 接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个 Socket 接口来实现。

  Windows Sockets 规范,它不是一种网络协议,而是一套开放的、支持多种协议的 Windows 下的网络编程接口。现在的 Winsock 已经基本上实现了与协议无关,可以使用 Winsock 来调用多种协议的功能,但较常使用的是 TCP/IP 协议。

三 C/S下的socket通信

  C/S模式即我们平时经常提到的 客户端–服务器 模式。

  3.1网络软件的通用体系结构

  客户(Client)和服务器(Server)是指通信中所涉及的两个应用进程。客户端—服务器方式所描述的是进程之间服务和被服务的关系。在下图中,主机A运行客户程序而主机B运行服务器程序。

技术图片

3.2 最简单的Socket通信流程

  一个只有客户方向服务方发信息的单向通信,并且也只有客户方会主动提出断开连接的最简单的情形(相反过程的原理是一样的),其双方Socket之间的关系如下图所示。

技术图片

 

  由上面这个十分简单的过程很容易得出最简单的Socket通信流程,如下图所示。

 技术图片

客户机/服务器模式的建立基于以下两点:

  a)非对等作用

  b)通信完全是异步的。

客户机/服务器模式在操作过程中采取的是主动请示方式:首先服务器方要先启动,并根据请示提供相应服务。

四、网络字节顺序

  不同的计算机存放多字节值的顺序不同,有的机器在起始地址存放低位字节(低位先存),有的机器在起始地址存放高位字节(高位先存)。基于Intel的CPU,即我们常用的PC机采用的是低位先存。为保证数据的正确性,在网络协议中需要指定网络字节顺序TCP/IP协议使用16位整数和32位整数的高位先存格式。由于不同的计算机存放数据字节的顺序不同,这样发送方发送数据后,即使接收方接受到该数据,也有可能无法查看所接收到的数据。所以在网络中不同主机间进行通信,要统一采用网络字节顺序。

 

以上是关于mfc 关闭阻塞的socket监听线程 select怎么用的主要内容,如果未能解决你的问题,请参考以下文章

socket编程,简单多线程服务端测试程序

004-Tcp

关于JAVA的关闭serverSOCKET

BIONIOAIO

MFC socket编程

一起来写web server 06 -- 单线程非阻塞IO版本