<1>客戶端(Client):移動設備(手機/iPad等手持設備).php
客戶端通常就是前端/前臺等等.iOS,android開發都是前端開發.html
<2>服務器(Server):爲客戶端提供服務(好比數據/資源等)的機器---本質也是一臺計算機(+服務器軟件).前端
服務器開發就是後端/後臺開發.java/php/.net等.java
<3>請求(Request):客戶端向服務器索取數據.android
<4>響應(Response):服務器對客戶端請求作出的反應,通常就是返回數據給客戶端.編程
服務器:按開發階段來分,分爲兩種:後端
遠程服務器: 外網服務器.應用上線以後供全體用戶使用的服務器.速度取決於用戶的網速和服務器的性能.緩存
本地服務器: 內網服務器,測試服務器.開發測試階段使用的服務器.供內部開發測試人員使用.速度飛快.服務器
2.網絡中傳輸的都是二進制數據流. html/圖片/視頻數據...網絡
二進制數據流是如何被分組並傳輸的呢?
}
1.理解網絡 2.理解七層協議/五層模型 3.理解Socket.
{
應用層: 規定"應用程序"的數據格式. http / ftp /email 等. //紙條上寫的是啥?
傳輸層: 創建"端口"到"端口"之間的通訊. UDP/TCP 協議."端口". //咱們幫你傳紙條
網絡層: 肯定每一臺計算機的位置,創建"主機"到"主機"之間的通訊.IPv4協議,"IP地址". // 女孩的位置
數據鏈路層: 肯定1和0的分組方式.以太網協議:一組電信號就是一個數據包."MAC地址"/網卡/廣播. // 深情告白
物理層: 將電腦鏈接入網絡,傳輸電信號1和0. // 一張白紙
互聯網分層結構的好處:
上層的變更徹底不影響下層的結構.
Socket : "主機 + 端口"就是"Socket(套接字/插座)" ----- TCP/IP協議
}
1.理解數據包. 2.理解網絡通訊實質.
{
網絡通訊的基礎: 知道對方的MAC地址和IP地址.
網絡通訊的實質: 互相交換數據包.
數據包:
每個數據包都包含 "標頭"和"數據"兩個部分."標頭"包含本數據包的一些說明."數據"則是本數據包的內容.
以太網數據包: 最基礎的數據包.標頭部分包含了通訊雙方的MAC地址,數據類型等. '標頭'長度:18字節,'數據'部分長度:46~1500字節.
IP數據包: 標頭部分包含通訊雙方的IP地址,協議版本,長度等信息. '標頭'長度:20~60字節,"數據包"總長度最大爲65535字節.
TCP/UDP數據包:標頭部分包含雙方的發出端口和接收端口. UDP數據包:'標頭'長度:8個字節,"數據包"總長度最大爲65535字節,正好放進一個IP數據包. TCP數據包:理論上沒有長度限制,可是,爲了保證網絡傳輸效率,一般不會超過IP數據長度,確保單個包不會被分割.
應用程序數據包: 標頭部分規定應用程序的數據格式.數據部分傳輸具體的數據內容.
嵌套:
數據包層層嵌套,上一層數據包嵌套在下一層數據包的數據部分.最後統統由以太網數據包來進行數據傳遞.
分包/拆包:
通常傳遞的數據都比較大,會將數據包分割成不少個部分來傳遞.
拼包:
將接收到數據包按序號拼接起來,組成完整的數據包.
}
瞭解IP地址.
{
靜態IP地址:
固定不變的IP地址,須要用戶本身手動設置.
動態IP地址:
經過DHCP協議自動生成的IP地址.
DHCP協議:
經過DHCP協議,用戶得到本機的動態IP地址,子網掩碼,網關,DNS服務器等.
子網掩碼:
與IP地址配合使用判斷兩臺計算機是否位於同一個子網絡.
DNS服務器:
能夠將域名(網址)轉換成IP地址.
}
瞭解一個HTTP請求的完整過程.
{
1. URL(Uniform Resource Locator):
統一資源定位符.URL就是資源的地址,位置.經過一個URL可以找到互聯網上惟一的一個資源.
URL的基本格式: 協議://主機地址/路徑
協議:不一樣的協議表明不一樣的資源查找方式,資源傳輸方式.
{
URL中的常見協議:
<1>HTTP:超文本傳輸協議,在網絡開發中最經常使用的協議.訪問的是遠程的網絡資源.格式:http://...
<2>file:訪問的時本地計算機上的資源.格式:file://(不要再加主機地址了)
<3>FTP:訪問的是共享主機的文件資源.格式:ftp://
<4>mailto:訪問的是電子郵件地址.格式:mailto:
}
主機地址:存放資源的主機IP地址(域名).
路徑:資源在主機中得具體位置.
2. HTTP請求的完整過程:
<1> 請求: 客戶端發出請求.向服務器索要數據(操做數據).
<2> 響應: 服務器對客戶端的請求作出響應.返回客戶端所須要的數據.
3. 包裝一個HTTP請求
用 NSURLRequest 來包裝一個HTTP請求.能夠指定緩存策略和超時時間.
1> 緩存策略的選擇:NSURLRequestCachePolicy
{
NSURLRequestUseProtocolCachePolicy = 0,
// 默認的緩存策略,使用協議定義.
NSURLRequestReloadIgnoringLocalCacheData = 1,
// 忽略本地緩存,直接從原始服務器地址下載.
NSURLRequestReturnCacheDataElseLoad = 2,
// 只有在緩存中不存在數據時,才從原始地址下載
NSURLRequestReturnCacheDataDontLoad = 3,
// 只使用緩存數據,若是不存在緩存,則請求失敗. 用於沒有網絡鏈接的離線模式
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4,
// 忽略遠程和本地的數據緩存,直接從原始地址下載
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData = 1,
// 忽略緩存,直接從原始服務器地址下載.
NSURLRequestReloadRevalidatingCacheData = 5,
// 驗證本地數據和遠程數據是否相同,若是不一樣則下載遠程數據,不然使用本地數據.
}
"理解"什麼是Socket.
{
0.
nc -lk 端口號 :始終監聽本地計算機此端口的數據.
1.導入三個頭文件
{
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
}
2.Socket書寫步驟
{
1.建立客戶端Socket socket(<#int#>, <#int#>, <#int#>);
2.建立服務器Socket struct sockaddr_in serverAddress;
3.鏈接到服務器(Socket編程) connect(<#int#>, <#const struct sockaddr *#>, <#socklen_t#>);
4.發送數據給服務器 send(<#int#>, <#const void *#>, <#size_t#>, <#int#>)
5.接收服務器返回的數據 recv(<#int#>, <#void *#>, <#size_t#>, <#int#>)
6.關閉 Socket close(socketNumber)
}
/*
建立客戶端 Socket.
三個參數: domain:網絡地址類型 type:端口類型 protocal:傳輸協議
domain:協議域 指定socket主機地址類型. 網絡層協議 AF_INET/IPv4協議; AF_INET_6/IPv6協議
type:指定Socket端口類型. 指定傳輸層協議類型(TCP/UDP),SOCK_STREAM(TCP/流) ,SOCK_DGRAM(UDP/報文頭)
protocal:指定傳輸協議:經常使用協議:IPPROTO_TCP、IPPROTO_UDP等,分別對應TCP傳輸協議、UDP傳輸協議.
最後一個參數傳0,會根據第二個參數,自動選擇第二個參數對應的協議.
返回值:若是 > 0 表示成功.
*/
// 0.建立客戶端 Socket.
int socketNumber = socket(AF_INET, SOCK_STREAM, 0);
if (socketNumber > 0) {
NSLog(@"Socket建立成功:%d",socketNumber);
}else{
NSLog(@"Socket建立失敗");
};
/*
鏈接到服務器.
三個參數:
1.客戶端socket.
2.接收方的socket參數.
3.數據長度.
返回值: 0 表示成功,其餘: 錯誤代號.
*/
// 1.服務器socket
struct sockaddr_in serverAddress;
// IPv4協議.
serverAddress.sin_family = AF_INET;
// 接收方(服務器)IP地址.
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
// 端口號.
serverAddress.sin_port = htons(56789);
// 2.鏈接到服務器
// serverAddress 的數據長度.
socklen_t length = sizeof(serverAddress);
// 鏈接服務器.
// 在C語言中,傳遞結構體的時候,會指定結構體的長度
// &取的是數據的起始位置,只有傳遞一個數據的長度,纔可以保證拿到完整的結構體數據.
// 返回值:0成功,其餘都是失敗.
int connection = connect(socketNumber, (const struct sockaddr *)&serverAddress,length);
if (!connection) {
NSLog(@"鏈接成功%d",connection);
}else{
NSLog(@"鏈接失敗");
}
/*
發送消息到服務器
參數:
1> 客戶端Socket.
2> 發送內容地址.
3> 發送內容長度.
4> 發送方式標識,通常爲0.
*/
// 3.發送消息到服務器
// 發送消息內容
NSString *msg = @"hello socket!";
msg.length :表示的是OC字符串的長度.
msg.UTF8String :將OC字符串轉換成 UTF8 的 ASCII 碼,一個漢字須要佔用3個字節的長度.
strlen :計算全部 ASCII 碼的長度.
// 發送消息
ssize_t result = send(socketNumber, msg.UTF8String, strlen(msg.UTF8String), 0);
NSLog(@"result = %ld",result);
/*
接收服務器接返回的消息
參數:
1> 客戶端Socket.
2> 接收內容緩存區.
3> 接收內容緩存區長度.
4> 接收方式.0表示阻塞式.必須等待服務器返回數據.
返回值:
若是成功,則返回接收到的字節數.失敗則返回SOCKET_ERROR
*/
// 4.服務器接收消息
// 建立接收內容緩存區.
uint8_t buffer[1024];
// 接受消息
ssize_t len = recv(socketNumber, buffer, sizeof(buffer), 0);
NSLog(@"len: %zd",len);
// 取出接受內容緩存區中的數據.
NSData *data = [NSData dataWithBytes:buffer length:len];
// 將二進制流數據data轉換成字符串類型.
NSString *receive = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"receive:%@",receive);
// 5.關閉Socket
close(socketNumber);
}