5.4.2接受客户端请求线程

  AcceptThread()实现接受客户端的连接请求。该函数是一个for循环体。当服务器处于运行状态时,bServerRunning变量为TRUE,不断地等待客户端的连接请求。当服务器处于即将退出状态时,bServerRunning变量为假,该线程退出。

for循环体中,使用sServer非阻塞套接字不断调用accept()函数。当没有客户端请求接受时,accept()函数立即返回WSAEWOULDBLOCK错误代码。在此情况下,首先调用Sleep()函数使该线程睡眠TIMEFOR_THREAD_SLEEP时间。然后执行continue语句,继续等待客户端的连接请求。

当完成接受客户端请求时,accept()函数返回新建连接的sAccept套接字。sAccept套接字继承sServer套接字的属性。该套接字也将以非阻塞方式工作于在其调用的函数上。

然后,在临界区内使用sAccept套接字和addrClient客户端地址为参数创建一个CClient类的实例。将该实例作为一个节点加入clientlist链表中。

最后调用CClient类的StartRuning()函数,为该客户端创建接收和发送数据线程。关于CClient类将在下面一节中介绍。接受客户端请求线程的程序清单如下。

#define TIMEFOR_THREAD_SLEEP                  500            //等待客户端请求线程睡眠时间

/**

 * 接受客户端请求

 */

DWORD __stdcall AcceptThread(void* pParam)

{

         SOCKET  sAccept;                                                          //接受客户端连接的套接字

         sockaddr_in addrClient;                                                  //客户端SOCKET地址

 

         for (;bServerRunning;)                                                                                           //服务器的状态

         {

                   memset(&addrClient, 0, sizeof(sockaddr_in));                                      //初始化

                   int                        lenClient = sizeof(sockaddr_in);                                             //地址长度

                   sAccept = accept(sServer, (sockaddr*)&addrClient, &lenClient);       //接受客户请求

 

                   if(INVALID_SOCKET == sAccept )

                   {

                            int nErrCode = WSAGetLastError();

                            if(nErrCode == WSAEWOULDBLOCK)      //无法立即完成一个非阻挡性套接字操作

                            {

                                     Sleep(TIMEFOR_THREAD_SLEEP);

                                     continue;                                                 //继续等待

                            }else {

                                     return 0;                                                  //线程退出

                            }

                   }

                   else                                                                            //接受客户端的请求

                   {

                            CClient *pClient = new CClient(sAccept,addrClient);         //创建客户端对象

                            EnterCriticalSection(&csClientList);                             //进入在临界区

                            clientlist.push_back(pClient);                                        //加入链表

                            LeaveCriticalSection(&csClientList);                                     //离开临界区

                           

                            pClient->StartRuning();                                 //为接受的客户端建立接收数据和发送数据线程

                   }

         }

 

         return 0;//线程退出

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值