1.Socket簡介
- Socket 又稱為"套接字",,它與網(wǎng)絡(luò)相關(guān),學(xué)網(wǎng)絡(luò)必學(xué)的一個(gè)知識
- 網(wǎng)絡(luò)上的兩個(gè)程序通過一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個(gè)連接的每一端都稱為一個(gè)socket
- 應(yīng)用程序通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者答應(yīng)網(wǎng)絡(luò)請求
2.網(wǎng)絡(luò)通信的要素
- 網(wǎng)絡(luò)上的請求就是通過Socket 來建立連接然后互相通信
- IP地址(網(wǎng)絡(luò)上主機(jī)設(shè)備的唯一標(biāo)識)
- 端號口(定位程序)
<1>用于標(biāo)示進(jìn)程的邏輯地址,不同進(jìn)程的表示
<2>有效端口:0-65535,其中0-1024由系統(tǒng)使用或者保留端口,開發(fā)中建議只用1024以上端口 - 傳輸協(xié)議 (用什么樣的方式進(jìn)行交互)
<1>通訊的規(guī)則
<2>常見的協(xié)議:TCP,UDP
(1)TCP (傳輸控制協(xié)議)
1.建立連接,形成傳輸數(shù)據(jù)的通道
2.在連接中進(jìn)行大數(shù)據(jù)傳輸(數(shù)據(jù)不受限制)
3.通過3次握手完成連接:目的是可靠協(xié)議,安全送達(dá)
4.必須建立連接效率會稍低
(2)UDP (用戶數(shù)據(jù)報(bào)協(xié)議)<不需要3次連接>
1.將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接
2.每個(gè)數(shù)據(jù)報(bào)的大小限制在64k之內(nèi)
3.因?yàn)闊o需連接,因此是不可靠協(xié)議
4.不需要建立連接,速度快
3.Socket通信流程圖
- HTTP 底層是通過socket建立連接通信管道,實(shí)現(xiàn)數(shù)據(jù)傳輸
- HTTP 是一個(gè)TCP的傳輸協(xié)議(方式),它是一個(gè)可靠,安全的協(xié)議
4.實(shí)現(xiàn)Socket服務(wù)端監(jiān)聽
- 實(shí)現(xiàn)socket 的監(jiān)聽方法
<1>使用C語言實(shí)現(xiàn)
<2>使用CocoaAsyncSocket (OC) 第三方框架,內(nèi)部都是對C的封裝
Telnet命令 : telnet host port/telnet 192.168.10.10 5228
Telnet命令是連接服務(wù)器上的某個(gè)端口對應(yīng)的服務(wù)
<3>講解一下Socket服務(wù)端對客戶端請求的處理(以10086為形式來模擬)- 下面是oc命令行來寫的
1.在gitHub下載 CocoaAsyncSocket
2.取出來里面的source->GCD
- 下面是oc命令行來寫的
3.我們需要建立一個(gè)Socket對象
4.終端輸入來連接服務(wù)端,然后敲Enter 來輸入一些想要發(fā)送給服務(wù)器的內(nèi)容,在JKServeLestening.m進(jìn)行返回輸入的內(nèi)容,實(shí)現(xiàn)自問自答
telnet 192.168.80.102 5228
5.重要的是掌握服務(wù)器端接受數(shù)據(jù)和返回?cái)?shù)據(jù)的處理
在終端輸入 telnet 192.168.80.102 5228 后有個(gè)選擇,3是退出服務(wù)器連接
6.具體的代碼都在JKServeLestening類里面自己下載
5.群聊服務(wù)器端
- 多個(gè)客戶連接到服務(wù)器
- 當(dāng)一個(gè)客戶端發(fā)送消息時(shí),服務(wù)器轉(zhuǎn)發(fā)給其他已經(jīng)連接的客戶端
- 相當(dāng)于一個(gè)群聊的意思
- 我們可以打開多個(gè)終端,來進(jìn)行群聊操作
在返回給用戶信息時(shí)判斷一下就好了
這里有兩個(gè)比較重要的屬性(端口號非常重要)
端口號:當(dāng)一個(gè)手機(jī)有多個(gè)QQ的時(shí)候,為了區(qū)分外面的手機(jī)給他的兩個(gè)QQ發(fā)送時(shí),用端口號來區(qū)分的到底應(yīng)該發(fā)給哪個(gè)QQ
/*
//服務(wù)器IP地址
@property (atomic, readonly, nullable) NSString *connectedHost;
//端口號
@property (atomic, readonly) uint16_t connectedPort;
*/
/*
服務(wù)器這邊讀取數(shù)據(jù)
*/
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
/*
1.把 NSData 轉(zhuǎn)化我 string
*/
NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//把當(dāng)前客戶端的數(shù)據(jù)轉(zhuǎn)發(fā)給其他客戶端
NSLog(@"接收到客戶端的數(shù)據(jù) = %@",string);
for (GCDAsyncSocket *socket in self.clientSocketS) {
if (socket != sock) {
[socket writeData:data withTimeout:-1 tag:0];
}
}
/*
2.處理請求,返回?cái)?shù)據(jù)給客戶端
*/
#warning 每次讀取完數(shù)據(jù)后,都要調(diào)用一次監(jiān)聽數(shù)據(jù)的方法
[sock readDataWithTimeout:-1 tag:0]; //(客戶端有請求就調(diào)用下面的方法)
}
6.群聊客戶端(和上面的服務(wù)器是保持一致的)
- 客戶端也需要GCDAsyncSocket對象,掛代理GCDAsyncSocketDelegate
- 里面與服務(wù)器連接成功需要監(jiān)聽,讀取完數(shù)據(jù)還需要監(jiān)聽 (否則可能只有一次數(shù)據(jù))
[sock readDataWithTimeout:-1 tag:0];
//1.連接到聊天服務(wù)器
//1.1創(chuàng)建一個(gè)客戶端的socket對象
GCDAsyncSocket *clientSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
self.clientSocket = clientSocket;
//1.2發(fā)送鏈接請求
NSError *error = nil;
[clientSocket connectToHost:@"192.168.80.102" onPort:5228 error:&error];
/*
讀取數(shù)據(jù)
*/
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
//讀完數(shù)據(jù)也要監(jiān)聽
[sock readDataWithTimeout:-1 tag:0];
}
/*
與服務(wù)器連接成功
*/
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
NSLog(@"與服務(wù)器連接成功");
//監(jiān)聽讀取數(shù)據(jù)(只有如此才會讀取下面方法中的數(shù)據(jù))
[sock readDataWithTimeout:-1 tag:0];
}
/*
與服務(wù)器斷開連接
*/
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSLog(@"斷開連接= %@",err);
}
7.上面5和6的匯總
- 一個(gè)客戶端和一個(gè)服務(wù)器端,你需要把客戶端里面的IP改為自己電腦的IP地址,端口 大于1024就好,自己隨便設(shè),但是服務(wù)器端和客戶端要保持一致
下面是代碼:在此只是模擬 群聊
服務(wù)器端群聊和客戶端群聊代碼
8.長連接和短連接
長連接和短連接其實(shí)就是一個(gè)連接的保存狀態(tài),區(qū)別就是連接保存的時(shí)間
講解一下:Socket層上的協(xié)議(Http協(xié)議與XMPP協(xié)議都是定義數(shù)據(jù)傳輸格式)
<1>Socket是層上的協(xié)議,指的是數(shù)據(jù)傳輸?shù)母袷?br> <2>Http協(xié)議其實(shí)是它就是定義在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)格式,雙方互相約束,也是數(shù)據(jù)傳輸?shù)母袷?/p>XMPP協(xié)議,是一款即時(shí)通訊協(xié)議
<1>可擴(kuò)展消息處理現(xiàn)場的協(xié)議,是基于可擴(kuò)展標(biāo)記語言(XML)的協(xié)議,它用于即時(shí)消息(IM)以及在線探測,這個(gè)協(xié)議可能最終允許因特網(wǎng)用戶向因特網(wǎng)其他任何人發(fā)送即時(shí)消息具體的分析一下下面的協(xié)議
以寫一封信為標(biāo)準(zhǔn):
** TCP/UDP (傳輸方式 ) ->EMS/申通/圓通**
HTTP/XMPP(數(shù)據(jù)傳輸格式) ->>新的內(nèi)容格式 (中文或,英文)
9.簡述即時(shí)通訊
- 即時(shí)通訊,又稱實(shí)時(shí)通訊
- 即時(shí)通訊(Instant MessageIng,簡稱IM) 是一個(gè)實(shí)時(shí)通信系統(tǒng),允許兩人或者多人使用網(wǎng)絡(luò)實(shí)時(shí)的傳遞文字消息,文件,語音與視頻交流
- 即時(shí)通訊在開發(fā)中使用的場景
<1>開發(fā)一個(gè)類似于微信,QQ,易信的聊天軟件
<2>在電商APP集成買家和賣家的實(shí)時(shí)溝通等等 - 當(dāng)前時(shí)下,實(shí)現(xiàn)即時(shí)通訊的方案
<1> XMPP(開源的即時(shí)通訊)
<2> 環(huán)信
- XMPP協(xié)議是一個(gè)即時(shí)通訊的協(xié)議,在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)格式是XML,它是通過TCP/IP連接到服務(wù)器.
綜述:環(huán)信是在XMPP上的的二次開發(fā)