自己動手寫iPhone wap瀏覽器之BSD Socket引擎篇(手把手教你iphone開發 – 進階篇)

來源:互聯網
上載者:User

作者:孫東風 2009-12-01(轉載請註明出處)

 

在《自己動手寫iPhone wap瀏覽器之預備篇》中筆者講述了進行iPhone wap瀏覽器開發的主要流程如下:

²        封裝BSD Socket進行HTTP請求。

²        將請求到的WML頁面解析成XML資料結構。

²        渲染需要在介面上顯示的WML標籤(英文名tag)。

²        將渲染後的WML標籤顯示在介面上(UIView)。

 

在《html" target=_blank>自己動手寫iPhone wap瀏覽器之預備篇》中已經講述了利用tinyxml解析請求到的XML頁面內容的知識,這個章節裡主要講述利用BSD Socket封裝HTTP引擎的知識。在筆者的文章《玩轉iPhone網路通訊之BSD Socket篇》中已經初步講解了iPhone中利用BSD Socket進行網路通訊的關鍵技術點,但是筆者只是把請求的WML頁面內容儲存在一個緩衝區內。在實際應用中,大多數情況下需要解析請求到的WML頁面內容從而區分開HTTP響應的包頭、包體,有時候還需要解析HTTP包頭的每行內容。要做到這些,首先需要BSD Socket引擎同步的解析請求到的資料,修改部分如下:

 

NSMutableString* readString = [[NSMutableString alloc] init];

char readBuffer[1];

 

int br = 0;

NSMutableString* readHeaderBufferStr = [[NSMutableString alloc] init];

while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)))

{

[readHeaderBufferStr appendString:[NSString stringWithCString:readBuffer length:sizeof(readBuffer)]];

 

if([self RecvRespHeaderFinished:readHeaderBufferStr])

{

break;

}else

{

}

}

 

筆者把緩衝區的大小改為1,這樣每次讀取一個字元到緩衝內並把每次讀取到的內容添加到readHeaderBufferStr內,之後調用RecvRespHeaderFinished:readHeaderBufferStr方法判斷HTTP頭部內容是否讀取完成,這個方法的實現如下:

 

- (BOOL)RecvRespHeaderFinished:(NSString*) aReadBuffer

{

    int len = [aReadBuffer length];

    if(len < 12)

    {

        return NO;

    }

   

    if([aReadBuffer characterAtIndex:(len-4)] == (const unichar)&&

        [aReadBuffer characterAtIndex:(len-3)] == (const unichar)&&

        [aReadBuffer characterAtIndex:(len-2)] == (const unichar)&&

        [aReadBuffer characterAtIndex:(len-1)] == (const unichar))

    {

        NSLog(@"ResponseHeader = %@",aReadBuffer);

        int nCode = [self GetResponseCode:aReadBuffer];

        NSLog(@"get http response code = %d",nCode);

       

        if(nCode > 299 || nCode < 200)

        {

            NSLog(@"ErrMsg:Server response code is %d.",nCode);

            close(sockfd);

        }

       

        contentlen = [[self GetHttpHdrFieldValue:aReadBuffer aField:EContentLength] intValue];

        NSLog(@"contentlen = %d",contentlen);

        return YES;

    }

   

    return NO;

}

 

筆者通過判斷緩衝字串的後四個字元是否依次為’’、’’、’’、’’來斷定HTTP頭部是否解析完成,如果解析完成則列印出來並返回YES,否則返回NO,最後並調用GetHttpHdrFieldValue:aReadBuffer:aField方法擷取HTTP包頭中指定行的value值,在這裡筆者需要擷取"Content-Length"的value值以便知道HTTP包體的長度,列印結果如下:

 

9-12-01 20:39:03.337 BSDHttpExample[253:207] getIpAddressForHost :220.181.37.183

2009-12-01 20:39:03.404 BSDHttpExample[253:207] Connect errno is :0

2009-12-01 20:39:03.404 BSDHttpExample[253:207] Then the conn is not -1!

2009-12-01 20:39:03.405 BSDHttpExample[253:207] httpCotent is :GET / HTTP/1.1

Host:wap.baidu.com

 

2009-12-01 20:39:03.406 BSDHttpExample[253:207] Sended content is :GET / HTTP/1.1

Host:wap.baidu.com

 

2009-12-01 20:39:03.406 BSDHttpExample[253:207] Datas have been sended over!

send 38 bytes to 220.181.37.183

2009-12-01 20:39:03.501 BSDHttpExample[253:207] ResponseHeader = HTTP/1.1 200 OK

Date: Tue, 01 Dec 2009 12:39:03 GMT

Server: Apache

Content-Length: 4638

Content-Type: text/vnd.wap.wml;charset=utf-8

Age: 0

Cache-Control: no-cache

Expires: -1

Set-Cookie: BAIDU_WISE_UID=frontui_1259671143_7379; Max-Age=800000000; expires=Sun, 08-Apr-35 18:52:23 GMT; path=/; domain=.baidu.com;

Vary: Accept-Encoding,User-Agent

Connection: close

 

 

可見,通過上面的方法成功的解析出來HTTP響應的頭部內容並擷取到HTTP包體的長度,那麼接下來就需要解析HTTP包體的內容了,代碼如下:

 

NSMutableString* readBodyBufferStr = [[NSMutableString alloc] init];

while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)))

{

if(recLen < contentlen)

{

recLen++;

[readBodyBufferStr appendString:[NSString stringWithCString:readBuffer length:sizeof(readBuffer)]];

}else

{

}

}

NSLog(@"hava received all data = %@",readBodyBufferStr);

 

通過判斷包體緩衝字串的長度和“Content-Length”的值來決定HTTP包體內容是否已經解析完成,列印結果如下:

 

2009-12-01 20:39:03.503 BSDHttpExample[253:207] contentlen = 4638

2009-12-01 20:39:03.532 BSDHttpExample[253:207] hava received all data =

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.