Author: Sun Dongfeng 2009-12-01 (source)
In the preparation for writing the iPhone wap browser by yourself, the author describes the main process of developing the iPhone wap browser as follows:
2. encapsulate BSD Socket for HTTP requests.
2. parse the requested WML page into an XML data structure.
2. The WML tag (English name tag) to be displayed on the interface for rendering ).
2. display the rendered WML labels on the UI (UIView ).
In html "target = _ blank> prepare an iPhone wap browser by yourself", I have learned how to parse the XML page content requested by tinyxml, this section describes how to encapsulate the HTTP Engine Using BSD Socket. The author's article "BSD Socket for iPhone network communication" has explained the key technical points of using BSD Socket for network communication in the iPhone, however, the author only saves the requested WML page content in a buffer zone. In practice, in most cases, You need to parse the WML page content of the request to distinguish the HTTP response header and package body. Sometimes you also need to parse each line of content in the HTTP header. To do this, the BSD Socket engine needs to synchronize the data parsed from the request. The modifications are as follows:
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
{
}
}
The author changes the buffer size to 1, so that each time a character is read to the buffer and the read content is added to readHeaderBufferStr, then the RecvRespHeaderFinished is called: the readHeaderBufferStr method is used to determine whether the HTTP header content is read successfully. The implementation of this method is as follows:
-(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;
}
The author determines whether the HTTP header is parsed by judging whether the last four characters of the buffer string are '', and'' in sequence, if the parsing is complete, print it out and return YES; otherwise, NO is returned. Finally, call the GetHttpHdrFieldValue: aReadBuffer: aField method to obtain the value of the specified row in the HTTP header, here, the author needs to obtain the value of "Content-Length" to know the Length of the HTTP packet body. The print result is as follows:
9-12-01 20:39:03. 337 BSDHttpExample [253: 207] getIpAddressForHost: 220.181.37.183
20:39:03. 404 BSDHttpExample [253: 207] Connect errno is: 0
20:39:03. 404 BSDHttpExample [253: 207] Then the conn is not-1!
20:39:03. 405 BSDHttpExample [253: 207] httpCotent is: GET/HTTP/1.1
Host: wap.baidu.com
20:39:03. 406 BSDHttpExample [253: 207] Sended content is: GET/HTTP/1.1
Host: wap.baidu.com
20:39:03. 406 BSDHttpExample [253: 207] Datas have been sended over!
Send 38 bytes to 220.181.37.183
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
It can be seen that the HTTP response header content is successfully parsed through the above method and the length of the HTTP packet body is obtained. Then, the HTTP packet body content needs to be parsed. The Code is as follows:
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 ed all data =%@", readBodyBufferStr );
Determine whether the Content of the HTTP packet body has been parsed by judging the Length of the buffer string and the value of "Content-Length". The result is as follows:
20:39:03. 503 BSDHttpExample [253: 207] contentlen = 4638
20:39:03. 532 BSDHttpExample [253: 207] hava received ed all data =
<? Xml version = "1.0" encoding = "UTF-8"?> <! DOCTYPE wml PUBLIC "-// WAPFORUM // dtd wml 1.1 // EN ""