登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: OpenSSL SSL_read non-blocking 非阻塞编程问题     [回主站]     [分站链接]
OpenSSL SSL_read non-blocking 非阻塞编程问题
clq
浏览(303) - 2018-02-08 16:05:05 发表 编辑

关键字: openssl

[2023-12-14 23:44:33 最后更新]
OpenSSL SSL_read non-blocking 非阻塞编程问题 2008-02-26 16:26:40

http://blog.chinaunix.net/uid-29846-id-2133948.html

分类:

因为在用SSL_read()的时候碰到过一些问题,现在总结一下。
环境:wince5.0 evc++4.0 OpenSSL0.9.8g CDMA连接
问题:CDMA连接建立后空闲一段时间后(一般4-5分钟),该连接就不能用了。要重新建立连接收发数据。
      但SSL_read()是阻塞方式,所以要等很长时间才返回(大概10分钟),用网线连接没有问题,用CDMA\GPRS连接才会有这个问题。
     
解决办法:
     虽然不知道引起这个问题的原因,还是找到一个办法让SSL_read()能快点返回。直到超时。
     在OpenSSL的帮助文档中查看关于SSL_read()的使用上提到了,可以用非阻赛方式来解决。
     1、用ioctlsocket设置socket为非阻塞方式。注意,OpenSSL握手之前不能设置为非阻塞方式。否则握手失败。
   注意,sockfd是普通的socket句柄。不是SSL socket句柄。
   int CTermSocket::SetSocketOpt(int sockfd, BOOL bBlock)
   {
    unsigned long ul = bBlock ? 0 : 1;
    int nRenCtl = ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul);
    if (nRenCtl)
    {
     nRenCtl = WSAGetLastError();
     return nRenCtl;
    }
    return nRenCtl;
   }    
   
   2、接收数据:
     接收数据的函数中,因为socket是非阻塞的方式,所以SSL_read()会立即返回,注意要判断错误码。
     如果是SSL_ERROR_WANT_READ,则要重新接收数据。
     OpenSSL文档中提到了要使用Select,我试过了,用Select来,前几次接收数据可以成功,但几次后就失败了,Select一直返回零,不知道是什么原因。
     虽然用非阻塞方式可以解决SSL_read()返回时间长的问题,但还是不知道socket连接为什么不能用。
    int CTermSocket::ssl_recv(char *buf, int len, int flags)
    {
     int res, count = 0;
     DWORD dwTick = ::GetTickCount();
    
     if(!m_sslSock)
     {
      return SOCKET_ERROR;
     }
    
     while(count < len)
     {
      if(::GetTickCount() - dwTick > (DWORD)m_timeout)
      {
       m_strErr.LoadString(IDS_ERR_RECV_TIMEOUT);
       return SOCKET_ERROR;
      }
      ::Sleep(10);
      DoEvents();
      
      res = SSL_read(m_sslSock, buf, len - count);
    
      int nRes = SSL_get_error(m_sslSock, res);
      if(nRes == SSL_ERROR_NONE)
      {
       if(res > 0)
       {
        count += res;
        dwTick = ::GetTickCount();
       }
      }
      else if (nRes == SSL_ERROR_WANT_READ)
      {
       continue;
      }
      else
      {
        m_strErr.Format(IDS_ERR_RECIEVE_FAILED, nRes);
       count = SOCKET_ERROR;
       break;
      }
     }
    
     return count;
    }
    
     3、发送数据:
       发送数据可接收数据查不多
    int CTermSocket::ssl_send(const char *buf, int len, int flags)
    {
     int res, count = 0;
     DWORD dwTick = ::GetTickCount();
    
     if(!m_sslSock)
     {
      return SOCKET_ERROR;
     }
    
     while(count < len)
     {
      if(::GetTickCount() - dwTick > (DWORD)m_timeout)
      {
       m_strErr.LoadString(IDS_ERR_SEND_TIMEOUT);
       return SOCKET_ERROR;
      }
      ::Sleep(10);
      DoEvents();
      
      res = SSL_write(m_sslSock, buf, len - count);
    
      int nRes = SSL_get_error(m_sslSock, res);
      if(nRes == SSL_ERROR_NONE)
      {
       if(res > 0)
       {
        count += res;
        dwTick = ::GetTickCount();
       }
      }
      else if (nRes == SSL_ERROR_WANT_WRITE)
      {
       continue;
      }
      else
      {
        m_strErr.Format(IDS_ERR_SEND_FAILED, nRes);
       count = SOCKET_ERROR;
       break;
      }
     }
    
     return count;
    }      
    
 
希望有哪位知道连接失效问题的请告诉我一声,谢谢
阅读(23152) | 评论(3) | 转发(0) |
1

上一篇:asdm的安装和配置

下一篇:经典网络词典
给主人留下些什么吧!~~

hljwsf2014-11-20 11:22:28

调用ssl_connect之前,可以把socket设置成非阻塞的。
while(1)
 {
  error = SSL_connect (ssl);
  if(error > 0)
  {
   std::cout<<"SSL_Connect success\n";
   return error;
  }
  std::cout<<"SSL_Connect fail\n";

  select(0,NULL,NULL,NULL,&tv);
  {
   ret = SSL_get_error(ssl,error);
   switch(ret)
  &
回复 | 举报

chinaunix网友2008-08-07 16:58:03

POST表单以后,服务器肯定要你保存COOKIE来保存登录状态的,你必须把上一次的COOKIE信息在HTTP头部再发回去
回复 | 举报

nkloverene2008-03-20 13:48:56

不知道您的连接失效问题解决了么 我刚开始看openssl,在win32下模拟登陆https服务器,然后post一个表单,但是我登陆服务器成功后,再post表单,返回的是session过期的提示页面。 不知道这个是怎么回事呢,望不吝赐教~




总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1