網絡通信

Socket:網絡上的兩個程序通過一個雙向的通信連接實現(xiàn)數(shù)據(jù)的交換温亲,這個連接的一端稱為一個socket豪娜。
socket.png
網絡通信要素
  • IP地址:網絡上主機設備的唯一標識
  • 端口號:服務器上有不同的應用程序泣棋,用于標示進程的邏輯地址败砂,不同進程的標示
傳輸協(xié)議
  • TCP:需要建立連接,傳輸數(shù)據(jù)大小不受限制猜扮,可靠協(xié)議、安全送達监婶,效率低
    a旅赢、HTTP底層就是通過socket建立連接通信管道,實現(xiàn)數(shù)據(jù)傳輸
    b、HTTP是一個TCP的傳輸協(xié)議(方式)鲜漩,它是一個可靠源譬,安全的協(xié)議
  • UDP:不需要建立連接集惋,數(shù)據(jù)大小有限制孕似,不可靠協(xié)議,傳輸速度快
    TCP/UDP是數(shù)據(jù)傳輸?shù)姆绞焦涡蹋鳫TTP/XMPP等一種數(shù)據(jù)傳輸?shù)母袷胶砑溃瑸榱朔奖憬邮蘸妥x取,你可以自己定義協(xié)議格式

網上看了小碼哥的視頻實現(xiàn)一個簡單的聊天室雷绢,列下核心代碼搞清楚中間發(fā)生了哪些事

//   服務端代碼

#import "XMGServiceListener.h"
#import "GCDAsyncSocket.h"  // 基于Scoket原生的框架 CocoaAsyncSocket github上有下

@interface XMGServiceListener()<GCDAsyncSocketDelegate>
@property (nonatomic, strong) GCDAsyncSocket *serverSocket;   /** 服務端的socket */
@property (nonatomic, strong) NSMutableArray *clientSockets;  //客戶端的所有socket對象
@end


@implementation XMGServiceListener

-(void)start{  // 開啟服務端
    // 1.創(chuàng)建一個socket對象
    // serverSocket 服務端的socket只監(jiān)聽 有沒有客戶端請求連接
    GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    
    // 2.綁定端口泛烙,并開啟監(jiān)聽,代表服務端已經開啟  端口號使用1024以上的 0-1024為系統(tǒng)端口
    NSError *error = nil;
    [serverSocket acceptOnPort:5288 error:&error];
    if (!error) {
        NSLog(@"服務開啟成功");
    }else{
        //失敗原因是端口被其它程序占用
        NSLog(@"服務開啟失敗 %@",error);
    }
    
    self.serverSocket = serverSocket;
}

#pragma mark 有客戶端的socket連接到服務器
-(void)socket:(GCDAsyncSocket *)serverSocket didAcceptNewSocket:(GCDAsyncSocket *)clientSocket{
    NSLog(@"serverSocket %@ ",serverSocket);
    NSLog(@"clientSocket %@ host:%@ port:%d",clientSocket,clientSocket.connectedHost,clientSocket.connectedPort);
    //1.保存客戶端的socket
    [self.clientSockets addObject:clientSocket];
    
    // 2.監(jiān)聽客戶端有沒有數(shù)據(jù)上傳
    //timeout -1 代表不超時
    //tag 標識作用翘紊,現(xiàn)在不用蔽氨,就寫0
    [clientSocket readDataWithTimeout:-1 tag:0];
    
    NSLog(@"當前有%ld 客戶已經連接到服務器",self.clientSockets.count);
    
}

#pragma mark 讀取客戶端請求的數(shù)據(jù)
-(void)socket:(GCDAsyncSocket *)clientSocket didReadData:(NSData *)data withTag:(long)tag{
    
    // 1.把NSData轉NSString
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
      
    // 2.把當前客戶端的數(shù)據(jù) 轉發(fā)給 其它的客戶端
    NSLog(@"接收到客戶端上傳的數(shù)據(jù):%@",str);
    for (GCDAsyncSocket *socket in self.clientSockets) {
        if (socket != clientSocket) { // 不發(fā)送給發(fā)消息的客戶端
            [socket writeData:data withTimeout:-1 tag:0]; 
    }
#warning 每次讀完數(shù)據(jù)后,都要調用一次監(jiān)聽數(shù)據(jù)的方法
    [clientSocket readDataWithTimeout:-1 tag:0];
}

@end
// 客戶端代碼

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 實現(xiàn)聊天室
    // 1.連接到群聊服務器
    // 1.1.創(chuàng)建一個客戶端的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.0.108" onPort:5288 error:&error];
    if (!error) {
        NSLog(@"%@",error);
    }
    
    // 2.發(fā)送聊天消息和接收聊天消息
    
}

-(void)socket:(GCDAsyncSocket *)clientSocket didConnectToHost:(NSString *)host port:(uint16_t)port{
    NSLog(@"與服務器連接成功");
    // 監(jiān)聽讀取數(shù)據(jù)
    [clientSocket readDataWithTimeout:-1 tag:0];
    
}

// Disconnect 斷開連接
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"與服務器斷開連接 %@",err);
}

#pragma mark 讀取消息
-(void)socket:(GCDAsyncSocket *)clientSocket didReadData:(NSData *)data withTag:(long)tag{

    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);
    NSLog(@"%@",[NSThread currentThread]);
    // 把消息添加到數(shù)據(jù)源
    if (str) {
        [self.dataSources addObject:str];
        
        // 刷新表格
#warning 要在主線程
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self.tableView reloadData];
        }];
    }
    // 監(jiān)聽讀取數(shù)據(jù)
    [clientSocket readDataWithTimeout:-1 tag:0];

}

- (IBAction)sendAction:(id)sender {
    // 發(fā)數(shù)據(jù)
    [self.clientSocket writeData:[@"hello world" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}

上面的聊天室是基于TCP的長鏈接帆疟,將客戶端socket從數(shù)組中移除就可以退出
XMPPFramework框架也是一種類似GCDAsyncSocket的框架鹉究,提供了一系列的方法去實現(xiàn)與服務端的連接和收發(fā)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市踪宠,隨后出現(xiàn)的幾起案子自赔,更是在濱河造成了極大的恐慌,老刑警劉巖柳琢,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绍妨,死亡現(xiàn)場離奇詭異,居然都是意外死亡柬脸,警方通過查閱死者的電腦和手機他去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倒堕,“玉大人灾测,你說我怎么就攤上這事∩荩” “怎么了行施?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長魂那。 經常有香客問我蛾号,道長,這世上最難降的妖魔是什么涯雅? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任鲜结,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘精刷。我一直安慰自己拗胜,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布怒允。 她就那樣靜靜地躺著埂软,像睡著了一般。 火紅的嫁衣襯著肌膚如雪纫事。 梳的紋絲不亂的頭發(fā)上勘畔,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音丽惶,去河邊找鬼炫七。 笑死,一個胖子當著我的面吹牛钾唬,可吹牛的內容都是我干的万哪。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼抡秆,長吁一口氣:“原來是場噩夢啊……” “哼奕巍!你這毒婦竟也來了?” 一聲冷哼從身側響起琅轧,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤伍绳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乍桂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冲杀,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年睹酌,在試婚紗的時候發(fā)現(xiàn)自己被綠了权谁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡憋沿,死狀恐怖旺芽,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情辐啄,我是刑警寧澤采章,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站壶辜,受9級特大地震影響悯舟,放射性物質發(fā)生泄漏。R本人自食惡果不足惜砸民,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一抵怎、第九天 我趴在偏房一處隱蔽的房頂上張望奋救。 院中可真熱鬧,春花似錦反惕、人聲如沸尝艘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽背亥。三九已至,卻和暖如春盔粹,著一層夾襖步出監(jiān)牢的瞬間隘梨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工舷嗡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嵌莉。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓进萄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锐峭。 傳聞我的和親對象是個殘疾皇子中鼠,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容

  • 由于最近面試中經常被問到關于網絡傳輸這一塊兒,再加上網上關于socket的帖子亂飛沿癞,除了幾篇精貼之外援雇,其余全部co...
    deeper_iOS閱讀 526評論 1 2
  • 1 網絡編程----TCPNo24 【 public class Server { public static...
    征程_Journey閱讀 1,238評論 0 4
  • 計算機網絡體系結構 OSI 的七層協(xié)議體系結構的概念清晰,理論完整,當時它既復雜又不實用; TCP/IP 體系結構...
    西風頌閱讀 1,097評論 2 9
  • TCP/IP協(xié)議 為了把全世界的所有不同類型的計算機都連接起來,就必須規(guī)定一套全球通用的協(xié)議椎扬,為了實現(xiàn)互聯(lián)網這個目...
    妄想成為正太的包蜀黍閱讀 469評論 0 0
  • 那個女孩 她有點傻還有點二 而他是個挺好的人 他們班同學在傳他們的緋聞 拿他們開玩笑 他和她每次只是笑笑 附和著同...
    柵有木兮閱讀 350評論 0 1