5.6.2 数据发送线程

  SendDataThread()函数完成客户端数据发送的功能。该函数外层是一个while循环体。当客户端与服务器处于连接状态时bConnectingTRUE,该函数处于循环状态。在循环中调用Sleep()函数使该线程睡眠TIMEFOR_THREAD_SLEEP时间。

当接收到发送数据的通知后,bSendDataTRUE,调用send()函数将发送缓冲区的数据发送出去。当数据发送完毕后,将bSendData变量值修改为FALSE。该线程等待下次数据发送。

下面说明,一种客户端被动关闭的情况。

q        主线程通知发送数据线程发送数据。然后,调用WaitForSingleObject()函数,等待显示数据结果hEventShowDataResult事件对象。而此时,由于某种原因客户端与服务器的连接断开,那么主线程被阻塞于该函数。

q        为此,在发送数据线程,当send()函数返回网络连接错误时,设置bConnecting变量为FALSE。同时,设置hEventShowDataResult事件对象为有信号状态。那么,主线程的WaitForSingleObject()函数会立即返回。并根据bConnecting变量值,判断此时与服务器连接已经断开。然后,主线程等待数据发送和接收线程退出。

SendDataThread()函数的程序清单如下。

#define TIMEFOR_THREAD_SLEEP          500                              //线程睡眠时间

/**

 * 发送数据线程

 */

DWORD __stdcall         SendDataThread(void* pParam)

{

         while(bConnecting)                                                                                     //连接状态

         {

                   if (bSendData)                                                                                     //发送数据

                   {

                            EnterCriticalSection(&csSend);                                               //进入临界区

                            for (;;)

                            {

                                     int nBuflen = ((phdr)(bufSend.buf))->len;

                                     int val = send(sClient, bufSend.buf, nBuflen,0);

                                     

                                      //处理返回错误

                                      if (SOCKET_ERROR == val)

                                      {

                                               int nErrCode = WSAGetLastError();

                                               if(WSAEWOULDBLOCK == nErrCode)         //发送缓冲区不可用

                                               {

                                                        continue;                                                     //继续循环

                                               }else {

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

                                                        bConnecting = FALSE;                        //断开状态

                                                        SetEvent(hEventShowDataResult);   //通知主线程,防止在无限期的等待返回结果。

                                                        return 0;

                                               }

                                      }

 

                                     bSendData = FALSE;                                           //发送状态

                                     break;                                                                            //跳出for循环

                            }                          

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

                   }

                  Sleep(TIMEFOR_THREAD_SLEEP);                                    //线程睡眠

         }

         return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值