1. 連接百度服務器
// 1. 連接百度的服務器
BOOL result = [self connectIp:@"220.181.111.188" port:80];
if (!result) {
NSLog(@"連接失敗");
return;
}
NSLog(@"連接成功");
// 連接服務器
- (BOOL)connectIp:(NSString *)ip port:(int)port {
int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
self.clientSocket = clientSocket;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip.UTF8String);
addr.sin_port = htons(port);
int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));
if (result == 0) {
return YES;
} else {
return NO;
}
}
2. 構造請求頭
// 模擬構造Http請求頭
NSString *request = @"GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"\r\n";
NSLog(@"%@", request);
3. 訪問服務器,并獲取返回內容
// 服務器返回的響應頭 響應體
NSString *response = [self sendAndRecv:request];
NSLog(@"返回的數(shù)據(jù): %@", response);
// 發(fā)送和接收數(shù)據(jù)
- (NSString *) sendAndRecv:(NSString *)sendMsg {
const char *msg = sendMsg.UTF8String;
ssize_t sendCount = send(self.clientSocket, msg, strlen(msg), 0);
NSLog(@"發(fā)送的字節(jié)數(shù) %zd", sendCount);
uint8_t buffer[1024];
NSMutableData *datas = [NSMutableData data];
ssize_t recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);
[datas appendBytes:buffer length:recvCount];
while (recvCount != 0) {
recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);
NSLog(@"接收的字節(jié)數(shù) %zd", recvCount);
[datas appendBytes:buffer length:recvCount];
}
NSString *recvMsg = [[NSString alloc] initWithData:datas encoding:NSUTF8StringEncoding];
return recvMsg;
}
4. 關閉連接,并將網頁顯示在UIWebView中
// 關閉連接
close(self.clientSocket);
// 截取響應頭,只保留響應體, 響應頭結束的標識 \r\n\r\n
// 找指定字符串所在的范圍,從它之后的第一個位置開始截取字符串
NSRange range = [response rangeOfString:@"\r\n\r\n"];
// 截取響應體
NSString *html = [response substringFromIndex:range.length + range.location];
// baseURL為html依賴的外部文件所在的地址
[self.webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.baidu.com"]];
5. 完成第四步之后,返回的網頁是PC版的
要想使得返回的網頁是手機版的,需要在添加請求頭時添加"User-Agent"這個請求頭,將第2步的請求頭內容更改為
// 模擬構造Http請求頭
NSString *request = @"GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n"
"Connection: keep-alive\r\n"
"\r\n";
NSLog(@"%@", request);
6. 完成代碼
//
// ViewController.m
// 請求百度
//
// Created by mazaiting on 18/1/3.
// Copyright ? 2018年 mazaiting. All rights reserved.
//
#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic, assign) int clientSocket;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 連接百度的服務器
BOOL result = [self connectIp:@"220.181.111.188" port:80];
if (!result) {
NSLog(@"連接失敗");
return;
}
NSLog(@"連接成功");
// 模擬構造Http請求頭
NSString *request = @"GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n"
"Connection: keep-alive\r\n"
"\r\n";
NSLog(@"%@", request);
// 服務器返回的響應頭 響應體
NSString *response = [self sendAndRecv:request];
NSLog(@"返回的數(shù)據(jù): %@", response);
// 關閉連接
close(self.clientSocket);
// 截取響應頭,只保留響應體, 響應頭結束的標識 \r\n\r\n
// 找指定字符串所在的范圍,從它之后的第一個位置開始截取字符串
NSRange range = [response rangeOfString:@"\r\n\r\n"];
// 截取響應體
NSString *html = [response substringFromIndex:range.length + range.location];
// baseURL為html依賴的外部文件所在的地址
[self.webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.baidu.com"]];
}
// 連接服務器
- (BOOL)connectIp:(NSString *)ip port:(int)port {
int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
self.clientSocket = clientSocket;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip.UTF8String);
addr.sin_port = htons(port);
int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));
if (result == 0) {
return YES;
} else {
return NO;
}
}
// 發(fā)送和接收數(shù)據(jù)
- (NSString *) sendAndRecv:(NSString *)sendMsg {
const char *msg = sendMsg.UTF8String;
ssize_t sendCount = send(self.clientSocket, msg, strlen(msg), 0);
NSLog(@"發(fā)送的字節(jié)數(shù) %zd", sendCount);
uint8_t buffer[1024];
NSMutableData *datas = [NSMutableData data];
ssize_t recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);
[datas appendBytes:buffer length:recvCount];
while (recvCount != 0) {
recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);
NSLog(@"接收的字節(jié)數(shù) %zd", recvCount);
[datas appendBytes:buffer length:recvCount];
}
NSString *recvMsg = [[NSString alloc] initWithData:datas encoding:NSUTF8StringEncoding];
return recvMsg;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)prefersStatusBarHidden{
return YES;
}
@end