一.Socket: Socket又稱”套接字" 網路上的兩個程式通過一個雙向的通信鏈接實現數據的交換,這個連接的一端成為一個socket 應用程式通常通過”套接字”向網路發出請求或者應答網路請求 二.網路通信的要素 網路上的請求就是通過socket來建立鏈接然後互相通信 ip地址(網路上主機設備的唯 ...
一.Socket:
- Socket又稱”套接字"
- 網路上的兩個程式通過一個雙向的通信鏈接實現數據的交換,這個連接的一端成為一個socket
- 應用程式通常通過”套接字”向網路發出請求或者應答網路請求
二.網路通信的要素
- 網路上的請求就是通過socket來建立鏈接然後互相通信
- ip地址(網路上主機設備的唯一標識)
- 埠號(定位程式)
用於標示進程的邏輯地址,不同進程的標示
有效埠:0~65535,其中0~1024由系統使用或者保留埠,開發中建議使用1024以上的埠
- 傳輸協議
三.TCP和UDP TCP(傳輸控制協議)
- 建立鏈接,形成傳輸數據的通道
- 在鏈接中進行打暑假傳輸(數據不受到限制 )
- 通過三次握手完成鏈接,是可靠協議,安全送達
- 必須建立鏈接,效率會稍低
- 將數據及源和目的封裝成數據包中,不需要建立鏈接
- 每個數據報的大小限制在64k之內
- 因為無需鏈接,因此是不可靠協議
- 不需要建立鏈接,速度快
四.Socket通信流程圖
五.實現Socket服務端監聽
- 實現socket的方法
- Telnet命令
六.代碼的簡單實現
- 添加第三方框架cocoaAsyncSocket--->下載地址 https://github.com/robbiehanson/CocoaAsyncSocket
- 創建工程: 從第三方框架中拉入 GCDAsyncSocket.h GCDAsyncSocket.m
- 創建服務監聽對象

#import "ServiceListen.h" //引入頭文件 #import "GCDAsyncSocket.h" @interface ServiceListen()<GCDAsyncSocketDelegate> //服務端對象 @property(nonatomic,strong)GCDAsyncSocket *serverSocket; //保存客戶端對象 @property(nonatomic,strong)NSMutableArray *NewSockets;//客戶端socket對象 @end @implementation ServiceListen /** * 懶載入 */ -(NSMutableArray *)NewSockets { if (_NewSockets==nil) { _NewSockets=[NSMutableArray new]; } return _NewSockets; } /** * 開啟服務方法的實現 */ -(void)start{ //開啟10086服務 //服務端的socket只監聽 有沒客戶端請求鏈接 GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)]; //綁定埠,並開啟監聽,代表10086服務已經開啟 NSError *error=nil; [serverSocket acceptOnPort:5288 error:&error]; if (!error) { NSLog(@"10086服務開啟成功"); } else { NSLog(@"開啟失敗%@",error); } self.serverSocket=serverSocket; } #pragma mark 有客戶端socket鏈接到伺服器 /** * 有客戶端socket鏈接到伺服器調用 * * @param sock 服務端 * @param newSocket 客戶端 */ -(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { NSLog(@"服務端serverSocket %@",sock); NSLog(@"客戶端newSocket %@",newSocket); //保存客戶端的socket [self.NewSockets addObject:newSocket]; //提供服務 NSMutableString *serverStr = [NSMutableString string]; [serverStr appendString:@"歡迎光臨!!!請輸入下麵的數字選擇服務!\n"]; [serverStr appendString:@"[0]線上充值\n"]; [serverStr appendString:@"[1]線上投訴\n"]; [serverStr appendString:@"[2]優惠信息\n"]; [serverStr appendString:@"[3]特殊服務\n"]; [serverStr appendString:@"[4]退出\n"]; [newSocket writeData:[serverStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0]; //監聽客戶端有沒有數據上傳 //Timeout:-1 代表不超時 //tag:標識作用,現在不用 [newSocket readDataWithTimeout:-1 tag:0]; } #pragma mark 讀取客戶端的請求的數據 /** * 讀取客戶端的請求的數據 * * @param sock 客戶端 * @param data 數據 * @param tag 標記 */ -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { //1:NSData轉成NSString NSString *str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"讀取數據 sock: %@ %@",sock,str); //獲取客戶端返回的數據 NSInteger code = [str integerValue]; //預設給客戶端的數據 NSString *reponseStr=nil; switch (code) { case 0: reponseStr = @"沒有充值服務....\n"; break; case 1: reponseStr = @"當前沒有員工....\n"; break; case 2: reponseStr = @"打折優惠5折....\n"; break; case 3: reponseStr = @"特殊服務一個....\n"; break; case 4: reponseStr = @"退出成功....\n"; break; default: break; } //2.處理請求,返回數據給客戶端 [sock writeData:[reponseStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0]; if (code==4) { //移除客戶端 [self.NewSockets removeObject:sock]; } #warning 每次讀完數據後,都要調用一次監聽數據的方法 [sock readDataWithTimeout:-1 tag:0]; }View Code
- 實例化一個服務監聽對象,開始監聽

#import <Foundation/Foundation.h> #import "ServiceListen.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); //創建一個服務監聽對象 ServiceListen *listen=[[ServiceListen alloc] init]; //開始監聽 [listen start]; //開啟主運行迴圈,讓服務不能停 [[NSRunLoop mainRunLoop]run]; } return 0; }View Code
- 運行程式 ,打開終端效果