1. case ECmwapConn:
  2.                 {       
  3.                 //对以前的数据进行清理
  4.                         iPrintBuf.SetLength(0) ;
  5.                         iFirstIn = ETrue ;
  6.                         if(iHttpDown) delete iHttpDown ;   
  7.                        
  8.                         //new出下载引擎进行链接
  9.                         iHttpDown = CM5HttpDown::NewL(*this, HTTP_DOWN_CMWAP) ;
  10.                         iHttpDown->HttpConnPorxy(s8) ; //s8为网址
  11.                         iRecvSize = 0 ;
  12.                        
  13.                        
  14.                         // check whether the file exists
  15.                         User::LeaveIfError(iFs.Connect()) ;
  16.                         iRecvSize = 0 ;
  17.                         if(BaflUtils::FileExists(iFs, KTargetFilename)) {
  18.                                 TInt seek_pos = 0 ;
  19.                                 iFile.Open(iFs, KTargetFilename, EFileStream | EFileWrite) ;
  20.                                 if(iFile.Size(iRecvSize) != KErrNone)
  21.                                         iRecvSize = 0 ;
  22.                                         //如果文件存在并且没有异常的话,打开文件并移到文件末尾,为追加模式
  23.                                 iFile.Seek(ESeekEnd, seek_pos) ;
  24.                         } else {
  25.                                 iFile.Replace(iFs, KTargetFilename, EFileStream | EFileWrite) ;
  26.                         }
  27.                         break ;
  28.                 }
  29.                
  30.                
  31. //下面来看CM5HttpDown引擎

  32. //那么这个是我们引擎给外界提供的观察者
  33. class M5HttpDownNotifier {
  34. public:
  35.         virtual void M5PrintNotify(const TDesC & aMessage) = 0 ;
  36.         virtual void M5RecvNotify(const TDesC8 & recv_buf) = 0 ;
  37.         virtual void M5TimerExpireNotify() = 0 ;
  38.         virtual void M5ErrorNotify(const TDesC& aErrMessage, TInt aErrCode = 0) = 0 ;
  39. };
  40. #endif


  41. class CM5HttpDown : public CBase, public MUINotifier {
  42.        
  43. protected:
  44.     // socket data
  45.         TInt                                     m_down_type ;
  46.     CSocketsEngine *                 m_sock_eng ;         //联网的socke引擎,此类肯定是比较重要的一部分
  47.     TBool                                         m_running ;
  48.     TBool                                         m_is_first_resp ;
  49.     TInt                                     m_web_port ;
  50.     TInt                                     m_total_bytes ;
  51.     TInt                                         m_recv_bytes;
  52.         TBuf8<HTTP_SEND_BUF_LEN> m_send_buf ;
  53.         TBuf8<HTTP_TEMP_BUF_LEN> m_web_addr ;
  54.         TBuf8<HTTP_TEMP_BUF_LEN> m_web_fname ;
  55.         M5HttpDownNotifier&                 m_m5_notifier ;         //给外界提供的接口
  56.    
  57. public: // MUINotifier implements
  58.         void PrintNotify(const TDesC& aMessage, TUint aAttributes = 0) ;
  59.         void RecvNotify(const TDesC8& aMessage) ;
  60.         void ErrorNotify(const TDesC& aErrMessage, TInt aErrCode)  ;
  61.         void SetStatus(const TDesC& aStatus) ;

  62. protected:        //自己使用的方法
  63.         TInt  Str2Int(const TDesC8 & s) ;
  64.         TBool CheckRecv(const TDesC8& recv_buf) ;
  65.     TBool ParseUri(TDesC8&  uri, TDes8& web_addr, TDes8& web_fname, TInt& web_port) ;
  66.     TBool ParseWebFileInfo(const TDesC8& recv_buf, TInt& total_length, TInt& jump_len) ;
  67.     TBool GetRespField(const TDesC8& recv_buf, TDesC8& field_name, TDesC8& end_flag, TDes8& res) ;
  68.                         
  69.     TBool InitSock(TDesC8& server_name, TInt server_port) ;
  70.     TBool SendReq(TDesC8& req_str) ;
  71.     TBool CloseSock() ;

  72. private:
  73.         CM5HttpDown(M5HttpDownNotifier & m5_notifier) ;
  74.         void ConstructL(TInt down_type) ;

  75. public:                //引擎暴露给外界的借口如下,当然还有观察者的那些接口用以通知
  76.         ~CM5HttpDown() ;
  77.         static CM5HttpDown * NewL(M5HttpDownNotifier& m5_notifie, TInt down_type) ;
  78.         static CM5HttpDown * NewLC(M5HttpDownNotifier& m5_notifier, TInt down_type) ;

  79.     TBool IsRunning() {return m_running ; }
  80.     TInt  HttpTotalSize() { return m_total_bytes ; }
  81.     TInt  HttpRecvSize() { return m_recv_bytes ; }

  82. //其实主要就暴露了以下三个接口
  83.         TBool HttpConnPorxy(TDesC8& uri) ;
  84.     TBool HttpDown(TDesC8& uri, TInt recv_bytes = 0) ;
  85.         TBool HttpStopDown() ;
  86. } ;
  87. #endif

  88. //下面来分析一下引擎暴露给我们接口
  89. TBool CM5HttpDown::HttpConnPorxy(TDesC8& uri)
  90. {
  91.         m_running = true ;
  92.        
  93.         //解析我们传递进去的URL:地址  文件名称 端口号,当让HTTP是80
  94.         ParseUri(uri, m_web_addr, m_web_fname, m_web_port) ;
  95.        
  96.         if(m_down_type == HTTP_DOWN_CMWAP) {
  97.                 TBuf8<20> proxy_svr ;
  98.                 proxy_svr.Copy(KCMCCWapProxy) ;         //_LIT(KCMCCWapProxy, "10.0.0.172") ;
  99.                
  100.                 //我们看到如果是wap链接,传递进去的是wap的代理地址,至于原理是什么,我们再慢慢分析
  101.                 if(!InitSock(proxy_svr, 80)) return EFalse ;
  102.         } else {
  103.                 if(!InitSock(m_web_addr, m_web_port)) return EFalse ;
  104.         }
  105.         return ETrue ;
  106. }

  107. TBool CM5HttpDown::HttpDown(TDesC8& uri, TInt recv_bytes)
  108. {
  109.         TBuf8<20> tmp_str ;
  110.         m_recv_bytes = recv_bytes ;
  111.         m_send_buf.SetLength(0) ;
  112.        
  113.         //此处主要是对是否已经有下载下来的内容进行分析
  114.     if(m_recv_bytes == 0)
  115.     {
  116.            
  117.                 m_send_buf.Append(KHttpCommonGet1) ;
  118.                
  119.                 //如果是wap链接,这个地方放的是uri,否则为文件名称
  120.                 //此处实际是用Socket组织了一个http的包,打算发送
  121.                 if(m_down_type == HTTP_DOWN_CMWAP)
  122.                         m_send_buf.Append(uri) ;
  123.                 else
  124.                         m_send_buf.Append(m_web_fname) ;
  125.                 m_send_buf.Append(KHttpCommonGet2) ;
  126.                 m_send_buf.Append(m_web_addr) ;
  127.                 m_send_buf.Append(KHttpCommonGet3) ;
  128.                 tmp_str.Format(_L8("%d"), m_web_port) ;
  129.                 m_send_buf.Append(tmp_str) ;
  130.                 m_send_buf.Append(KHttpCommonGet4) ;
  131.                
  132.     }
  133.     else
  134.     {
  135.            
  136.                 m_send_buf.Append(KHttpResumeGet1) ;
  137.                 if(m_down_type == HTTP_DOWN_CMWAP)
  138.                         m_send_buf.Append(uri) ;
  139.                 else
  140.                         m_send_buf.Append(m_web_fname) ;
  141.                 m_send_buf.Append(KHttpResumeGet2) ;
  142.                 m_send_buf.Append(m_web_addr) ;
  143.                 m_send_buf.Append(KHttpResumeGet3) ;
  144.                 tmp_str.Format(_L8("%d"), m_web_port) ;
  145.                 m_send_buf.Append(tmp_str) ;
  146.                 //这里才是断点续传的要点,就是将已经下载的字节数传递到服务器(这个是HTTP协议本身来进行处理的)
  147.                 //不要想的有多神秘哦
  148.                 m_send_buf.Append(KHttpResumeGet4) ;
  149.                 tmp_str.Format(_L8("%d"), m_recv_bytes) ;
  150.                
  151.                 m_send_buf.Append(tmp_str) ;
  152.                 m_send_buf.Append(KHttpResumeGet5) ;
  153.                
  154.     }

  155.     // send the request
  156.     //进行socke发送
  157.     return SendReq(m_send_buf) ;
  158. }

  159. //关闭链接
  160. TBool CM5HttpDown::HttpStopDown()
  161. {
  162.     return CloseSock() ;
  163. }


  164. //通过上面的观察,我们发现,我们现在需要弄明白
  165. //SendReq(m_send_buf) ;
  166. //InitSock(proxy_svr, 80)的实现,下面我们来看看,我也是学习,说的乱不要怪哦,呵呵

  167. TBool CM5HttpDown::InitSock(TDesC8& server_name, TInt server_port)
  168. {
  169.         TBuf<50> svr_name ;
  170.         svr_name.Copy(server_name) ;
  171.         m_sock_eng->SetServerName(svr_name) ;
  172.         m_sock_eng->SetPort(server_port) ;
  173.         m_sock_eng->ConnectL() ;
  174.     return ETrue ;
  175. }

  176. TBool CM5HttpDown::SendReq(TDesC8& req_str)
  177. {
  178.         if(m_sock_eng->Connected()) {
  179.                 m_sock_eng->WriteL(req_str) ;
  180.                 return ETrue ;
  181.         }
  182.     return EFalse ;
  183. }

  184. //我们看到,其实上面的两个函数很简单,无非就是发送和链接,设置参数,主要功能是由
  185. //SocketEngine来实现的,我们去看看socketengine吧

  186. //这是对SocketEngine进行了一段截取

  187. #ifndef HTTP_DOWN_CMWAP
  188. #define HTTP_DOWN_CMWAP                         0
  189. #define HTTP_DOWN_CMNET                         1
  190. #endif

  191. class CSocketsEngine : public CActive, public MTimeOutNotifier, public MEngineNotifier
  192.     {
  193. public: // new methods
  194.        
  195.         //这些是我们比较关心的接口
  196.     void ConnectL();
  197.     void Disconnect();
  198.         void WriteL(const TDesC8& aData);
  199.         void Read();


  200. //我们需要对以下接口也进行关注和注意
  201.         TUint32 CreateCmnetIap() ;
  202.         TUint32 CreateCmwapIap() ;
  203.         void ConnectSmoothCMNET() ;
  204.         void ConnectSmoothCMWAP() ;
  205.         void ConnectL(TUint32 aAddr);
  206. }



  207. //下面我们对上面说需要注意的方法进行分析;
  208. void CSocketsEngine::ConnectL()
  209.     {
  210.     // Initiate connection process
  211.     if (iEngineStatus == ENotConnected)
  212.         {
  213.         TInetAddr addr;
  214.         if (addr.Input(iServerName) == KErrNone)
  215.             {
  216.             // server name is already a valid ip address
  217.             ConnectL(addr.Address());
  218.             }
  219.         else // need to look up name using dns
  220.             {
  221.           //如果发现不合法,则需要去寻找IP地址,域名解析
  222.                 // Initiate DNS
  223.                 User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp));
  224.                 // DNS request for name resolution
  225.                 iResolver.GetByName(iServerName, iNameEntry, iStatus);
  226.                 
  227.                 //将引擎状态进行改变,方便RunL函数去进行处理
  228.                 ChangeStatus(ELookingUp);
  229.                 // Request time out
  230.                 iTimer->After(KTimeOut);
  231.                 SetActive();
  232.             }
  233.         }
  234.     }



  235. void CSocketsEngine::WriteL(const TDesC8& aData)
  236.     {
  237.     // Write data to socket
  238.         if (iEngineStatus == EConnected)
  239.         {
  240.                         iSocketsWriter->IssueWriteL(aData);
  241.         }
  242.     }
  243.        
  244. void CSocketsEngine::Read()
  245.     {
  246.     // Initiate read of data from socket
  247.         if ((iEngineStatus == EConnected) && (!iSocketsReader->IsActive()))
  248.         {
  249.         iSocketsReader->Start();
  250.         }
  251.     }

  252. // from CActive
  253. void CSocketsEngine::RunL()
  254.     {
  255.     // Active object request complete handler.
  256.     // iEngineStatus flags what request was made, so its
  257.     // completion can be handled appropriately
  258.         iTimer->Cancel(); // Cancel TimeOut timer before completion

  259.         switch(iEngineStatus)
  260.             {
  261.             case EConnecting:
  262.                     // IP connection request
  263.                     if (iStatus == KErrNone)
  264.                         // Connection completed successfully
  265.                         {
  266.                                 //如果链接成功,则开始监听读取
  267.                                         ChangeStatus(EConnected);
  268.                                         Read(); //Start CSocketsReader Active object
  269.                         }
  270.                     else
  271.                         {
  272.                             iSocket.Close();
  273.                             iConsole.ErrorNotify(KErrConnectionFailed, iStatus.Int());
  274.                             ChangeStatus(ENotConnected);
  275.                 }
  276.                     break;
  277.             case ELookingUp:
  278.                     iResolver.Close();
  279.                     if (iStatus == KErrNone)
  280.                         {
  281.                                 //域名解析成功则开始链接
  282.                             // DNS look up successful
  283.                             iNameRecord = iNameEntry();

  284.                             // Extract domain name and IP address from name record
  285.                             Print(KStrDomainName);
  286.                             Print(iNameRecord.iName);

  287.                             TBuf<15> ipAddr;
  288.                             TInetAddr::Cast(iNameRecord.iAddr).Output(ipAddr);

  289.                             Print(KStrIPAddr);
  290.                             Print(ipAddr);
  291.                             Print(KStrNewLine);

  292.                             // And connect to the IP address
  293.                             ChangeStatus(ENotConnected);
  294.                             ConnectL(TInetAddr::Cast(iNameRecord.iAddr).Address());
  295.                         }
  296.                     else
  297.                         {       
  298.                             // DNS lookup failed
  299.                             iConsole.ErrorNotify(KErrDNSFailed, iStatus.Int());
  300.                             ChangeStatus(ENotConnected);
  301.                         }
  302.                     break;
  303.             default:
  304.             User::Panic(KPanicSocketsEngine, ESocketsBadStatus);
  305.             break;

  306.             };
  307.     }
  308.    

  309.        
复制代码

3rd断点续传.rar

36.63 KB, 下载次数: 2296

已有 1 人评分技术分 收起 理由
dymx101 + 5

总评分: 技术分 + 5   查看全部评分

遨游于移动平台开发中
高级构架师 2# smilepander 发表于 2010-9-10 23:33:04
  1. //感觉又被骗了,socketEngine本身并没有进行读写,而是有reader和writer来完成的,所以我又厚着脸皮来了

  2. //Reader中我们只需要关心IssueRead和Runl,了解它是怎么发起的,还有就是它怎么对读取的东西进行操作的。

  3. void CSocketsReader::IssueRead()
  4.     {
  5.     // Initiate a new read from socket into iBuffer
  6.     __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicSocketsEngineRead, ESocketsBadState));
  7.     iSocket.RecvOneOrMore(iBuffer, 0, iStatus, iDummyLength);
  8.     SetActive();
  9.     }
  10.   
  11.   void CSocketsReader::RunL()
  12.   {
  13.   // Active object request complete handler
  14.   switch (iStatus.Int())
  15.       {
  16.       case KErrNone:
  17.               //没有错误,通知外边然后继续读取,发现reader好无私,一直默默的读取哦
  18.           // Character has been read from socket
  19.           iEngineNotifier.ResponseReceived(iBuffer);
  20.             IssueRead(); // Immediately start another read
  21.           break;
  22.       case KErrDisconnected:
  23.               //如果已经断开了链接,也通知外边
  24.           iEngineNotifier.ReportError(MEngineNotifier::EDisconnected,
  25.                                       iStatus.Int());
  26.           break;
  27.       default:
  28.               //其他错误都报呈是读取错误,reader也不知道怎么回事了,如果你知道的话就帮忙给补充一下吧,呵呵
  29.           iEngineNotifier.ReportError(MEngineNotifier::EGeneralReadError,
  30.                                       iStatus.Int());
  31.           break;
  32.       }       
  33.   }
  34.   
  35.   //下面来看writer
  36.   
  37.   
  38.   void CSocketsWriter::IssueWriteL(const TDesC8& aData)
  39.     {
  40.     if ((iWriteStatus != EWaiting) && (iWriteStatus != ESending))
  41.         {
  42.         User::Leave(KErrNotReady);
  43.         }

  44.     if ((aData.Length() + iTransferBuffer.Length()) > iTransferBuffer.MaxLength())
  45.         {
  46.         // Not enough space in buffer
  47.         User::Leave(KErrOverflow);
  48.         }

  49.         // Add new data to buffer
  50.         iTransferBuffer.Append(aData);
  51.        
  52.         //其实发现上面就是将数据写到缓冲区中

  53. //等待活动对象比较清闲的时候进行发送
  54.     if (!IsActive())
  55.         {
  56.         SendNextPacket();
  57.         }
  58.     }
  59.    
  60.     void CSocketsWriter::SendNextPacket()
  61.     {
  62.     if (iTransferBuffer.Length() > 0)
  63.         {
  64.         // Move data from transfer buffer to actual write buffer
  65.         iWriteBuffer = iTransferBuffer;
  66.         iTransferBuffer.Zero();
  67.             iSocket.Write(iWriteBuffer, iStatus); // Initiate actual write
  68.        
  69.         // Request timeout
  70.             iTimer->After(iTimeOut);
  71.             SetActive();
  72.             iWriteStatus = ESending;
  73.         }
  74.     else
  75.         {
  76.             iWriteStatus = EWaiting;
  77.         }
  78.     }
  79. //至此,我们学会了用socket封装HTTP,也知道了HTTP断点续传的东西,可是好奇怪,
  80. //我们应该关注的有几个函数并没有用到,为什么呢,要不我们去看看他们构造的时候都干嘛了

  81. void CSocketsEngine::ConstructL(TInt down_type)
  82. {
  83.         ChangeStatus(ENotConnected);

  84.         // Start a timer
  85.         iTimer = CTimeOutTimer::NewL(EPriorityHigh, *this);
  86.         CActiveScheduler::Add(this);

  87. //我们这时候发现,此处是非常重要的一部分,因为他们能默默的去链接网络,而不用惊动用户,
  88. //相信这也是大家在做网络的时候梦寐以求的东西,我们一块去瞧瞧吧
  89.         // Open channel to Socket Server
  90.         if(down_type == HTTP_DOWN_CMNET)
  91.                 ConnectSmoothCMNET() ;
  92.         else
  93.                 ConnectSmoothCMWAP() ;

  94.         // Create socket read and write active objects
  95.         iSocketsReader = CSocketsReader::NewL(*this, iSocket);
  96.         iSocketsWriter = CSocketsWriter::NewL(*this, iSocket);
  97. }

  98. //无声的链接wap
  99. void CSocketsEngine::ConnectSmoothCMWAP()
  100. {
  101. #ifdef __WINSCW__
  102.         User::LeaveIfError(iSocketServ.Connect()) ;
  103. #else
  104.         TBuf<20> iap_name_buf ;
  105.         TBuf<20> cmwap_str ;
  106.         TUint32  iap_id = -1 ;

  107.         cmwap_str.Append(KCmwapIapName) ;

  108.         // prepare conn
  109.         User::LeaveIfError(iSocketServ.Connect());
  110.         User::LeaveIfError(iConn.Open(iSocketServ)) ;

  111.         // visit commdb for iap
  112.         CCommsDatabase* const comm_db = CCommsDatabase::NewL(EDatabaseTypeIAP);
  113.         CleanupStack::PushL(comm_db);

  114.         // visit the table of comm_db
  115.         CCommsDbTableView *iap_table_view = comm_db->OpenTableLC(TPtrC(IAP));

  116.         // switch pointer to the first iap record
  117.         if(iap_table_view->GotoFirstRecord() == KErrNone) {
  118.                 // search comm_db for cmnet iap
  119.                 do {
  120.                         // get the iap name from comm_db
  121.                         iap_name_buf.SetLength(0) ;
  122.                         iap_table_view->ReadTextL(TPtrC(COMMDB_NAME), iap_name_buf);

  123.                         // test the cmnet iap name
  124.                         if((iap_name_buf.Find(cmwap_str) != KErrNotFound)) {
  125.                                 iap_table_view->ReadUintL(TPtrC(COMMDB_ID), iap_id) ;
  126.                                 break ;
  127.                         }
  128.                 } while (KErrNone == iap_table_view->GotoNextRecord()) ;
  129.         }
  130.         CleanupStack::PopAndDestroy(2, comm_db); // iap_table_view, comm_db

  131.         if(iap_id == -1) iap_id = CreateCmwapIap() ;

  132.         // use the iap, construct preference
  133.         TCommDbConnPref conn_pref;
  134.         conn_pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt) ;
  135.         conn_pref.SetDirection(ECommDbConnectionDirectionOutgoing) ;
  136.         conn_pref.SetBearerSet(ECommDbBearerGPRS) ;
  137.         conn_pref.SetIapId(iap_id) ;

  138.         // perform the smooth connection
  139.         iConn.Start(conn_pref);
  140. #endif
  141. }


  142. //无声的链接cmnet
  143. void CSocketsEngine::ConnectSmoothCMNET()
  144.         {
  145. #ifdef __WINSCW__
  146.                 User::LeaveIfError(iSocketServ.Connect()) ;
  147. #else
  148.                 TBuf<20> iap_name_buf ;
  149.                 TBuf<20> cmnet_str ;
  150.                 TUint32 iap_id = -1 ; // set invalid iap first
  151.                
  152.                 cmnet_str.Append(KCmnetIapName) ;

  153.                 // prepare conn
  154.                 User::LeaveIfError(iSocketServ.Connect());
  155.                 User::LeaveIfError(iConn.Open(iSocketServ)) ;

  156.                 // visit commdb for iap
  157.                 CCommsDatabase* const comm_db = CCommsDatabase::NewL(EDatabaseTypeIAP);
  158.                 CleanupStack::PushL(comm_db);

  159.                 // visit the table of comm_db
  160.                 CCommsDbTableView *iap_table_view = comm_db->OpenTableLC(TPtrC(IAP));

  161.                 // switch pointer to the first iap record
  162.                 if(iap_table_view->GotoFirstRecord() == KErrNone) {
  163.                         // search comm_db for cmnet iap
  164.                         do {
  165.                                 // get the iap name from comm_db
  166.                                 iap_name_buf.SetLength(0) ;
  167.                                 iap_table_view->ReadTextL(TPtrC(COMMDB_NAME), iap_name_buf);

  168.                                 // test the cmnet iap name
  169.                                 if((iap_name_buf.Find(cmnet_str) != KErrNotFound)) {
  170.                                         iap_table_view->ReadUintL(TPtrC(COMMDB_ID), iap_id) ;
  171.                                         break ;
  172.                                 }
  173.                         } while (KErrNone == iap_table_view->GotoNextRecord()) ;
  174.                 }
  175.                 CleanupStack::PopAndDestroy(2, comm_db); // iap_table_view, comm_db

  176.                 // make sure the iap is valid
  177.                 if(iap_id == -1) iap_id = CreateCmnetIap() ;

  178.                 // use the iap, construct preference
  179.                 TCommDbConnPref conn_pref;
  180.                 conn_pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt) ;
  181.                 conn_pref.SetDirection(ECommDbConnectionDirectionOutgoing) ;
  182.                 conn_pref.SetBearerSet(ECommDbBearerGPRS) ;
  183.                 conn_pref.SetIapId(iap_id) ;

  184.                 // perform the smooth connection
  185.                 iConn.Start(conn_pref);
  186. #endif
  187.         }
  188.        
  189.        
  190.         //现在明白了怎么创建接入点,联网不弹出提示框,Socket封装HTTP,断点续传,感觉真不错呀,给大家分享,附件为完整的例子
复制代码
已有 1 人评分技术分 收起 理由
xiejiangquan + 5 写的不错 支持

总评分: 技术分 + 5   查看全部评分

遨游于移动平台开发中
研究员 3# wuyuezhouzhou 发表于 2010-9-10 23:35:13
还是标记一下的好,虽然也写过
研究员 4# symbian_love 发表于 2010-9-10 23:35:26
好东西,顶起
爱拼才会赢
研究员 5# cleanriceking 发表于 2010-9-10 23:36:38
直接放入收藏夹,以备后用
顺便顶起
赞一个
Shuddhodana
首席构架师 6# Sylvanas 发表于 2010-9-10 23:37:07
LZ够低调
谢谢
高级构架师 7# smilepander 发表于 2010-9-10 23:37:38
回复 5# cleanriceking


    饭王   哈哈   你原来是饭王啊
研究员 8# cleanriceking 发表于 2010-9-10 23:39:13
回复 7# smilepander

难道阁下是YoYo
见习构架师 9# jebai0521 发表于 2010-9-10 23:40:23
顶!!!!!!!!
首席构架师 10# Brian1900 发表于 2010-9-10 23:41:57
MARK
Everything happend for a reason!Work work hard,day day up!
高级构架师 11# drfang07 发表于 2010-9-10 23:44:13
收藏了,谢谢分享
中级构架师 12# vance 发表于 2010-9-10 23:49:02
感谢分享,学习了!!
大神,有几个问题我想请教。
第一,KCmwapIapName,您这个常量的内容是cmwap吗,不知道为什么,我的cmwap,cmnet匹配不到table里的iapname。我扫了一边table,打出来的iapname很多是中文,而我看很多的例子里都是cmnet等,这样能找到相应的name而获得相应的id吗?
第二,您在constructL里设置不提示连接接入点,程序开启的时候自动调用,但是这个过程我真机测试要6到8秒,这段时间内程序就像卡在那里一样,不知道您是不是也是这样?有什么好的解决方法没?
人始终是要有梦想的
中级构架师 13# yuanqiyao 发表于 2010-9-10 23:49:34
回复 12# vance
同意,一直想弄明白接入点对话框不弹出后时间的问题,我用的RConnection::Start的同步方法就感觉好慢,是不是异步会快点。。
高级构架师 14# smilepander 发表于 2010-9-10 23:50:06
回复 12# vance

1.KCmwapIapName是个字符串,你看附件那个例子吧,cmwap是移动,其他运营商好像不是这个名字,所以匹配的时候一般是用“wap”去匹配,而不是cmwap,如果实在找不到了,就创建一个吧  把例子里面的东西copy一下,哈哈!
2.你所说的联网慢的问题,就是因为你用的start方法是同步的方式,用异步方式去试试,我感觉还不错哦。
高级构架师 15# smilepander 发表于 2010-9-10 23:50:07
回复 13# yuanqiyao


    你的回答很正确呀!呵呵
首席构架师 16# 一脚盆的饭锅 发表于 2010-9-10 23:50:40
一般我找wap接入点会找 wap 移动梦网 彩信这几个关键字,这样就万无一失了哈哈
不要迷恋锅,锅只是菜锅
首席构架师 17# lanseshuibei 发表于 2010-9-10 23:50:52
顶一个!
高级构架师 18# lovexlm 发表于 2010-9-11 01:56:15
这个必须顶,多谢楼主啊
高级工程师 19# coowood001 发表于 2010-9-11 01:59:23
收藏了,谢谢楼主分享
初级工程师 20# 漫步ぁ随风 发表于 2010-9-11 02:09:11
收藏mark了.
您需要登录后才可以回帖 登录 | 注册

关于我们|手机版|Archiver|DEVDIV.COM ( 京ICP备07040843号 )  

GMT+8, 2012-5-19 16:55

Powered by DEVDIV.COM!

© 2010-2012 DEVDIV.COM Coummunity.

回顶部