Socket,TCP,UDP,HTTP基本通訊原理和OC版本Demo
非常通俗的例子->寄快遞
- TCP和UDP是傳輸方式—> 例如空運,輪渡,陸運
- HTTP,XMPP則是資料傳輸格式協議 –> 寄送的東西(吃的,用的,玩的。。。)
- socket理解為傳輸層和應用層之前的抽象物件,通過對TCP/IP傳世方式的封裝,呼叫其封裝好的方法就可實現通訊,但是必須知道雙方的IP,埠和協議–>就好比知道雙方的寄件地址
什麼是Socket?
TCP、UDP,HTTP 底層通訊都是通過 socket 套接字實現
網路上不同的計算機,也可以通訊,那麼就得使用網路套接字(socket)。
socket就是在不同計算機之間進行通訊的一個抽象。
他工作於TCP/IP協議中應用層和傳輸層之間的一個抽象
總結如下:
1.Socket 是對 TCP/IP 協議族的一種封裝,是應用層與TCP/IP協議族通訊的中間軟體抽象層。從設計模式的角度看來,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。
2.Socket 還可以認為是一種網路間不同計算機上的程式通訊的一種方法,利用三元組(ip地址(主機),協議(傳輸方式),埠(主機上的程式標誌))就可以唯一標識網路中的程式,網路中的程式通訊可以利用這個標誌與其它程式進行互動。
3.socket保證了不同計算機之間的通訊,也就是網路通訊。對於網站,通訊模型是客戶端伺服器之間的通訊。
兩個端都建立一個socket物件,然後通過socket物件對資料進行傳輸。通常伺服器處於一個無線迴圈,等待客戶端連線
通俗的理解:
Socket的英文原義是“孔”或“插座”,Socket通常也稱作”套接字”,用於描述IP地址和埠,是一個通訊鏈的控制程式碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般執行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原意那樣,像一個多孔插座。一臺主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務
網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket
應用程式通常通過”套接字”向網路發出請求或者應答網路請求
演示Demo
什麼是TCP
TCP(傳輸控制協議,HTTP的互動方式就是TCP互動方式,需要建立連線,一種面向連線的、可靠的位元組流服務)
在一個TCP連線中,僅有兩方進行彼此通訊。廣播和多播不能用於TCP
- 建立連線,形成資料傳輸通道
- 在連結中進行大資料傳輸,資料不受限制
- 通過三次握手完成連結,是可靠協議,安全送達協議
- 必須建立連線,效率很稍微低
所謂三次握手(Three-way Handshake),是指建立一個 TCP 連線時,需要客戶端和伺服器總共傳送3個包。
三次握手的目的是連線伺服器指定埠,建立 TCP 連線,並同步連線雙方的序列號和確認號,交換 TCP 視窗大小資訊。在 socket 程式設計中,客戶端執行 connect() 時。將觸發三次握手。
* 第一次握手(SYN=1, seq=x):
客戶端傳送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算連線的伺服器的埠,以及初始序號 X,儲存在包頭的序列號(Sequence Number)欄位裡。
傳送完畢後,客戶端進入 `SYN_SEND` 狀態。
* 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
伺服器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均為1。伺服器端選擇自己 ISN 序列號,放到 Seq 域裡,同時將確認序號(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。
傳送完畢後,伺服器端進入 `SYN_RCVD` 狀態。
* 第三次握手(ACK=1,ACKnum=y+1)
客戶端再次傳送確認包(ACK),SYN 標誌位為0,ACK 標誌位為1,並且把伺服器發來 ACK 的序號欄位+1,放在確定欄位中傳送給對方,並且在資料段放寫ISN的+1
傳送完畢後,客戶端進入 `ESTABLISHED` 狀態,當伺服器端接收到這個包時,也進入 `ESTABLISHED` 狀態,TCP 握手結束。
什麼是UDP
UDP (使用者資料包協議,無連線,不可靠的網路協議,用於多播,廣播,例如上課同步直播)
- 將資料以及源(我的電腦IP)和目的(別人電腦的IP)封裝成資料包中,不需要建立連線
- 每個資料包的大小限制在64k之內,為什麼小一點呢,例如你20分鐘的大小發一次,那出錯了,你這20分支都看不到了,
如果你一秒鐘發一次,你錯過了,下一秒就能繼續接上,所以大小有限制 - 無需連線,因此是不可靠協議
- 不需要建立連線,速度快
1. UDP協議的伺服器端流程
UDP協議的伺服器端程式設計的流程分為套接字建立、套接字與地址結構進行繫結、收發資料、關閉套接字等過程,分別對應於函式socket()、bind()、sendto()、recvfrom()和close()。
建立套接字過程使用socket()函式,這個過程與TCP協議中的含義相同,不過建立的套接字型別為資料包套接字。地址結構與套接字檔案描述符進行繫結的過程中,與TCP協議中的繫結過程不同的是地址結構的型別。當繫結操作成功後,可以呼叫recvfrom()函式從建立的套接字接收資料或者呼叫sendto()函式向建立的套接字傳送網路資料。當相關的處理過程結束後,需要呼叫close()函式關閉套接字。
2. UDP協議的客戶端流程
UDP協議的伺服器端程式設計的流程分為套接字建立、收發資料、關閉套接字等過程,分別對應於函式socket()、sendto()、recvfrom()和close()。
建立套接字過程使用socket()函式,這個過程與TCP協議中的含義相同,不過建立的套接字型別為資料包套接字。建立套接字之後,可以呼叫函式sendto()向建立的套接字傳送資料或者呼叫recvfrom()函式從建立的套接字收網路資料。當相關的處理過程結束後,需要呼叫close()函式關閉套接字。
3. UDP協議伺服器和客戶端之間的互動
UDP協議中伺服器和客戶端的互動存在於資料的收發過程中。進行網路資料收發的時候,伺服器和客戶端的資料是對應的:客戶端傳送資料的動作,對伺服器來說是接收資料的動作;客戶端接收資料的動作,對伺服器來說是傳送資料的動作。
UDP協議伺服器與客戶端之間的互動,與TCP協議的互動相比較,缺少了二者之間的連線。這是由於UDP協議的特點決定的,因為UDP協議不需要流量控制、不保證資料的可靠性收發,所以不需要伺服器和客戶端之間建立連線的過程。
什麼是HTTP
- HTTP底層就是通過Socket建立連結通訊管道,實現資料傳輸
- HTTP是一個TCP傳輸協議的其中一個方式,他是可靠的,安全的協議,和XMPP類似,一種定義好的資料格式傳輸協議
- HTTP構建於TCP/IP協議之上,預設埠號是80
- HTTP是無連線無狀態的
HTTP超詳細分解傳送門
寫個簡單的TCP服務端和客戶端互動的原理
1.使用-> CocoaAsyncSocket (7.5.1),用一個類封裝方法,開啟runloop迴圈
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
MKJSocketService *socketService = [[MKJSocketService alloc] init];
[socketService connected];
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
2.由於是服務端,我們需要一個服務端的socket以及一個可變陣列存放連線的客戶端socket
@interface MKJSocketService () <GCDAsyncSocketDelegate>
@property (nonatomic,strong) GCDAsyncSocket *serviceSocket; // 服務端socket
@property (nonatomic,strong) NSMutableArray *connectionClientSockets; // 已經連結的socket
@end
@implementation MKJSocketService
- (NSMutableArray *)connectionClientSockets
{
if (_connectionClientSockets == nil) {
_connectionClientSockets = [[NSMutableArray alloc] init];
}
return _connectionClientSockets;
}
- (instancetype)init
{
if (self = [super init]) {
/**
注意:這裡的服務端socket,只負責socket(),bind(),lisence(),accept(),他的任務到底結束,只負責監聽是否有客戶端socket來連線
*/
self.serviceSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
return self;
}
注意:這裡的服務端socket只是完成到監聽部分就結束了,後續的所有操作,read或者write或者其他都是客戶端Socket的呼叫
3.呼叫連線的方法,監聽可以連線 的客戶端
- (void)connected
{
NSError *error = nil;
// 給一個需要連線的埠,0-1024是系統的
[self.serviceSocket acceptOnPort:3666 error:&error];
if (error) {
NSLog(@"3666伺服器開啟失敗。。。。。");
}
else
{
NSLog(@"開啟成功,並開始監聽");
}
}
// 有客戶端連線該伺服器進行會話 Mac 終端下呼叫telnet IP port進行與伺服器的連結,如果連結上了就會呼叫這個方法
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
NSLog(@"伺服器%@",sock);
NSLog(@"客戶端%@ IP:%@,%d 連線成功",newSocket,newSocket.connectedHost,newSocket.connectedPort);
// 1.如果不用全域性變數存取,直接就會推出
[self.connectionClientSockets addObject:newSocket];
// 2.連線完成之後進行 客戶端的sock進行監聽狀態
[newSocket readDataWithTimeout:-1 tag:0];
// 3.write目的就是傳送資料 有人連線到服務端之後就進行一系列響應
NSMutableString *options = [NSMutableString string];
[options appendString:@"歡迎來到東莞 請輸入下面的數字選擇服務\n"];
[options appendString:@"[0]按摩\n"];
[options appendString:@"[1]洗腳\n"];
[options appendString:@"[2]大保健\n"];
[options appendString:@"[3]special services\n"];
[options appendString:@"[4]退出\n"];
// 服務端傳送資料
[newSocket writeData:[options dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}
注意:[newSocket readDataWithTimeout:-1 tag:0];
呼叫者不是服務端的socket,服務端的socket只負責到監聽部分,之後就不需要了,這裡的呼叫方是連線的客戶端,而且每次接受資料或者傳送資料之後都要呼叫,才能進行下一次的收發資料
4.接收到客戶端的訊息以及客戶端請求斷開如何操作
/**
這個是服務端的程式碼,這裡的write就是伺服器傳送資料,而且這裡的傳送socket物件也是連線的客戶端socket
當有連線好的客戶端之後傳送訊息給伺服器,就能通過該方法受到訊息,在通過訊息,服務端在進行write資料給客戶端展示
*/
- (void)socket:(GCDAsyncSocket *)clientSock didReadData:(NSData *)data withTag:(long)tag
{
NSString *receiveStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
switch ([receiveStr integerValue]) {
case 0:
[self writeDataWithSocket:clientSock message:@"按摩188,這邊請\n"];
break;
case 1:
[self writeDataWithSocket:clientSock message:@"洗腳288,這邊請\n"];
break;
case 2:
[self writeDataWithSocket:clientSock message:@"大保健啊小夥子,來來來\n"];
break;
case 3:
[self writeDataWithSocket:clientSock message:@"哎呦喂,可以啊,小夥子要來哪一套\n"];
break;
case 4:
[self exitSocket:clientSock];
break;
default:
[self writeDataWithSocket:clientSock message:@"沒有您要的服務\n"];
break;
}
[clientSock readDataWithTimeout:-1 tag:0];
}
/**
斷開連結呼叫
*/
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSLog(@"失去連線了");
}
/**
傳送資料給客戶端
*/
- (void)writeDataWithSocket:(GCDAsyncSocket *)socket message:(NSString *)msg
{
[socket writeData:[msg dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}
/**
斷開連線,會呼叫Connection closed by foreign host.
並且傳送資料到客戶端
最終從服務端的陣列中移除,釋放記憶體,斷開socket
@param socket 需要斷開的客戶端socket
*/
- (void)exitSocket:(GCDAsyncSocket *)socket
{
[self writeDataWithSocket:socket message:@"離開東莞\n"];
[self.connectionClientSockets removeObject:socket];
NSLog(@"currentSocket:%ld",self.connectionClientSockets.count);
}
5.一個建議的聊天客服功能就結束了,開啟Demo,然後執行起來,再開啟終端輸入
telnet IP地址 埠號 確認之後就是連結成功了,就可以一些簡單的互動了
相關文章
- 通訊協議:HTTP、TCP、UDP協議HTTPTCPUDP
- UDP和TCP以及HTTPUDPTCPHTTP
- SOCKET通訊中TCP、UDP資料包大小的確定TCPUDP
- TCP、UDP、HTTP及Socket的簡單講解TCPUDPHTTP
- 網路通訊——socket(TCP/IP).Http,同步和非同步的區別TCPHTTP非同步
- Android TCP socket通訊AndroidTCP
- .NET TCP、UDP、Socket、WebSocketTCPUDPWeb
- TCP、UDP、HTTP、SOCKET之間的區別與聯絡TCPUDPHTTP
- C# 通過socket實現UDP 通訊C#UDP
- Tcp, WebSocket 和 http 之間的通訊TCPWebHTTP
- TCP/IP、HTTP和Socket總結TCPHTTP
- HTTP、Socket與TCPHTTPTCP
- Linux學習/TCP Socket通訊LinuxTCP
- day30:TCP&UDP:socketTCPUDP
- socket.io通訊原理
- Socket套接字通訊原理
- 基於TCP/UDP的Socket程式設計,HTTP/HTTPS協議TCPUDP程式設計HTTP協議
- TCP和UDP實現簡單一對一通訊TCPUDP
- 在C++ Builder中用socket api來寫網路通訊程式(同時支援TCP和UDP協議)C++UIAPITCPUDP協議
- 聊聊UDP、TCP和實現一個簡單的JAVA UDP小DemoUDPTCPJava
- HTTP與UDP/TCP區別HTTPUDPTCP
- 手把手教你 Socket 通訊(TCP/IP)TCP
- 在C++ Builder中用socket api來寫網路通訊程式(同時支援TCP和UDP協議) (轉)C++UIAPITCPUDP協議
- http、socket、tcp的區別和聯絡?HTTPTCP
- TCP 和 UDPTCPUDP
- TCP和UDPTCPUDP
- 【Windows socket+IP+UDP+TCP】網路基礎WindowsUDPTCP
- 清晰易懂TCP通訊原理解析(附demo、簡易TCP通訊庫原始碼、解決沾包問題等)C#版TCP原始碼C#
- http tcp udp json 接收測試HTTPTCPUDPJSON
- Java網路程式設計UDP通訊原理Java程式設計UDP
- 懵逼的HTTP、Socket與TCPHTTPTCP
- Windows Socket程式設計精華《TCP通訊伺服器》Windows程式設計TCP伺服器
- socket通訊
- TCP和UDP比較TCPUDP
- TCP和UDP協議TCPUDP協議
- TCP和UDP對比TCPUDP
- TCP/IP 和SocketTCP
- socket udpUDP