socket 入門回顧, 直接上步驟
一砚亭、基礎(chǔ)知識(shí)
1.三大基礎(chǔ)認(rèn)識(shí)(IP
端口
協(xié)議
)
IP 端口 協(xié)議.png
- IP地址,(2^8)^4 ,可表示42億網(wǎng)絡(luò)設(shè)備,可貌似連世界總?cè)丝诘拿黠@不夠吧陋守。so,??
- 外網(wǎng)/內(nèi)網(wǎng), 路由器,解決這些問題。你要是訪問百度,全國(guó)各地,可能分配了不同的IP擎宝。
- 服務(wù)器有不同的服務(wù) ,前端 通過端口 來訪問響應(yīng)服務(wù) ,但一般不是直接通過端口號(hào)訪問服務(wù) , 通過協(xié)議
服務(wù)器端口.png
2.終端ping的玩一下
- ①ping 127.0.0.1 不通 和 ②ping 192.168.31.180不通, 兩者是有區(qū)別的。
- 前者不通代表網(wǎng)卡問題, 后者則是通過ping 路由器下發(fā)到子節(jié)點(diǎn)本機(jī)的,可能路由的問題了浑玛。
image.png
3.協(xié)議 (7層模型)
7層模型.png
- 計(jì)算機(jī)起源
第一臺(tái)computer用來打炮的
后來,計(jì)算機(jī)越來越多, 存儲(chǔ)數(shù)據(jù)方式-->磁帶打孔 存儲(chǔ)二進(jìn)制
再后來, 軟盤(媒介) 發(fā)明作為計(jì)算機(jī)之間通信數(shù)據(jù)方式
后來,科學(xué)家發(fā)現(xiàn) 二進(jìn)制數(shù)據(jù) 與 電流電信號(hào)(高低電平)一樣嘛,ok,走入正軌绍申。
- 七層模型底下3層(硬件) ,由通信芯片搞定,芯片代碼已經(jīng)寫死(效率非常高), 咱們是觸碰不到的, 咱就是站在巨人肩膀上開發(fā)
- socket是在傳輸層, 倆協(xié)議TCP、UDP顾彰。TCP/IP 協(xié)議是分不開的 , IP協(xié)議其實(shí)是在網(wǎng)絡(luò)層,我們用不到的拿不到的
image.png
- 上面三層,比較模糊,表示層极阅、會(huì)話層 許多協(xié)議都廢棄掉了,合成為一層 -- 應(yīng)用層
從傳輸層 拿到data, 怎么知道是一部電影還是一個(gè)小秘密呢,這就需要建立一個(gè)網(wǎng)絡(luò)會(huì)話(會(huì)話層),通過http協(xié)議在網(wǎng)絡(luò)會(huì)話中,按照協(xié)議特定的格式 對(duì)二進(jìn)制進(jìn)行解析
- 傳輸層, TCP/UDP保證計(jì)算機(jī)之間通信中拿到準(zhǔn)確的data ,但我咋知道你是啥數(shù)據(jù)呢??
- 會(huì)話層,兩個(gè)互相通 信的應(yīng)用進(jìn)程之間,建立涨享、組織和協(xié)調(diào)其交互(Interaction)
- 表示層, 負(fù)責(zé)在不同的數(shù)據(jù)格式之間進(jìn)行轉(zhuǎn)換操作(編碼筋搏、加密、壓縮)
4.深入?yún)f(xié)議UDP
& TCP
image.png
小問題: 猜一猜咱開發(fā)中幾種場(chǎng)景,用的UDP 還是TCP ?? (a)游戲 (b)大文件下載
答案: (a)UDP 會(huì)掉幀(掉1個(gè)64k內(nèi)的數(shù)據(jù)包) (b)TCP (安全 完整, 效率低) because??
注意點(diǎn): TCP連接握手三次,斷開握手四次
5.socket理解
image.png
想到socket 立馬想到 IP port ~
兩手機(jī)qq聊天, 手機(jī)a通過IP找到手機(jī),通過port找到應(yīng)用程序,然后建立連接,ok交流吧"約嗎?"
6.socket通訊示意圖
image.png
socket是跨平臺(tái)的,無論什么平臺(tái)(Android, ios ,c++...) 底層通訊都是??圖(此圖乃真理也,經(jīng)久不衰)
二厕隧、擼代碼
- 核心代碼
socket即網(wǎng)絡(luò), 這就是咱所用網(wǎng)絡(luò)(?NSURLSession/Connection/AFN...
等)最底層代碼了
// 創(chuàng)建
int socket(int domain, int type, int protocol);
// 連接
int connect(int, const struct sockaddr *, socklen_t) __DARWIN_ALIAS_C(connect);
// 發(fā)送數(shù)據(jù)
ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send); // void * 萬(wàn)能指針
// 讀取數(shù)據(jù)
ssize_t recv(int, void *, size_t, int) __DARWIN_ALIAS_C(recv);
// 關(guān)閉連接
int close(int);
-
socket連接成功
- image.png
-
步驟簡(jiǎn)單:
1.敲下??圖中代碼(設(shè)置本機(jī)
和12345
端口號(hào))
2.終端命令行使 始終監(jiān)聽本地計(jì)算機(jī)12345端口的數(shù)據(jù) ??$ nc -lk 12345
Netcat , 終端下 用于調(diào)試檢查網(wǎng)絡(luò)的工具包,可用于創(chuàng)建TCP/IP連接
3.run
懶人copy的如下??
// 頭文件引入
import <sys/socket.h> // socket
#import <netinet/in.h> // 互聯(lián)網(wǎng)
#import <arpa/inet.h> // 互聯(lián)網(wǎng)參數(shù)
// 1. 創(chuàng)建socket
/**
domain: 協(xié)議域 AF_INET -> IPV4
type: socket類型 ,SOCK_STREAM -> TCP , SOCK_DGRAM -> UDP
protocol: IPPROTO_TCP, 如果0 , 自動(dòng)選擇,根據(jù)上個(gè)(第二個(gè))參數(shù)而定
return: socket
*/
int clientSocket = socket(AF_INET, SOCK_STREAM, 0); // 6
// 2. 連接
/**
client socket:
(地址)指針: 指向 結(jié)構(gòu)體sockaddr (目標(biāo)(server)的 port ip)
結(jié)構(gòu)體數(shù)據(jù)長(zhǎng)度:
return: 0 成功
*/
struct sockaddr_in serverAddr;
serverAddr.sin_port = htons(12345); // htons 該宏 專用于寫 端口號(hào) // 20480(高地位互換)
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 底層ip地址也是一串二進(jìn)制
int connResult = connect(clientSocket, (const struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (connResult == 0) {
NSLog(@"socket connet successfully");
}else{
NSLog(@"socket connet fail %zd",connResult);
return;
}
// 3. 發(fā)送數(shù)據(jù)
/**
參數(shù)
client socket:
發(fā)送內(nèi)容指針
發(fā)送內(nèi)容長(zhǎng)度
發(fā)送方式標(biāo)志, 一般為0
返回值
如果成功, 則返回字節(jié)數(shù)
*/
NSString * msg = @"hello socket";
//const char * msg1 = "hello socket 1";
ssize_t sendLen = send(clientSocket, msg.UTF8String, strlen(msg.UTF8String), 0);
NSLog(@"send %ld",sendLen);
// 4. 讀取數(shù)據(jù)
.
.
. // 更多請(qǐng)去GitHub Demo
}
-
UI搭建
image.png
三奔脐、拓展
- 思考 :
如何通過socket連接百度server呢? 直接將127.0.0.1換成www.baidu.com可以嗎? - 接下來, try一try~ ??圖
image.png
but: 發(fā)現(xiàn) 發(fā)送hello, 沒有響應(yīng), why ? (server根本看不懂 我發(fā)的"hello")
因?yàn)? 它是網(wǎng)頁(yè)請(qǐng)求, 需要使用http協(xié)議, socket是最底層的了,可沒有幫你封裝處理http .
-
看看網(wǎng)頁(yè)請(qǐng)求格式
真正發(fā)送給服務(wù)器的數(shù)據(jù).png看到??request header, 這就是真正發(fā)送給服務(wù)器的數(shù)據(jù)
再 try ~
將那些request header內(nèi)容 復(fù)制到 發(fā)送內(nèi)容中, 通過socket發(fā)送,即可收到server的response了
超懶人 點(diǎn)擊 github | <a >demo</a> 下載 調(diào)試 俄周。
祝愿有所收獲哦 ~ _ ~