Socket的簡單使用,Socket簡單使用
一.Socket:
- Socket又稱”通訊端"
- 網路上的兩個程式通過一個雙向的通訊連結實現資料的交換,這個串連的一端成為一個socket
- 應用程式通常通過”通訊端”向網路發出請求或者應答網路請
二.網路通訊的要素
- 網路上的請求就是通過socket來建立連結然後互相通訊
- ip地址(網路上主機裝置的唯一標識)
- 連接埠號碼(定位程式)
用於標示進程的邏輯地址,不同進程的標示
有效連接埠:0~65535,其中0~1024由系統使用或者保留連接埠,開發中建議使用1024以上的連接埠
通訊的規則-->常見協議:TCP UDP 三.TCP和UDPTCP(傳輸控制通訊協定)
- 建立連結,形成傳輸資料的通道
- 在連結中進行打暑假傳輸(資料不受到限制 )
- 通過三向交握完成連結,是可靠協議,安全送達
- 必須建立連結,效率會稍低
UDP(使用者資料包通訊協定)
- 將資料及源和目的封裝成資料包中,不需要建立連結
- 每個資料報的大小限制在64k之內
- 因為無需連結,因此是不可靠協議
- 不需要建立連結,速度快
四.Socket通訊流程圖
五.實現Socket服務端監聽
1.使用c語言實現 2.使用cocoaAsyncSocket(OC)第三方架構,內部是對C的封裝
telnet host port/telnet --> 192.168.10.10 5288 1.telnet命令是連結的伺服器上的某個連接埠對應的服務 2.host : 系統偏好-->網路-->IP 3.host: 有效連接埠:0~65535,其中0~1024由系統使用或者保留連接埠,開發中建議使用1024以上的連接埠 六.代碼的簡單實現
- 添加第三方架構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