利用AsyncSocket來實現客戶端與服務端,客戶端與客戶端的通信

作者:Love@YR
鏈接:http://blog.csdn.net/jingqiu880905/article/details/52121666
請尊重原創,謝謝!

此篇博文是對他人一個聊天demo的總結。
先大致說下這個demo
一共3個viewController:
ClientViewController,ServerViewController,ChatViewController

ClientViewController做的事情:
1. 向服務端發送數據,這個數據就幾個字段,值都是空字串,只是爲了服務端能因此拿到客戶端的ip而已。接收服務端發來的所有連接服務端的客戶端的ip並顯示在列表上。
2. 監聽其他客戶端的聊天請求,如果有收到聊天的socket,彈框選擇聊或者不聊,聊的話就進入ChatViewController頁面去打字。

ServerViewController做的事情:
從上面描述可以看出ServerViewController所做就是監聽有無客戶端的連接請求,收到的話連上,然後讀取客戶端發來數據,然後發給客戶端所有連上服務端的客戶端ip數據。

ChatViewController做的事情:
進入ChatViewController有兩種方式,一個是在ClientViewController上直接點擊我想聊的那個IP的cell,主動去聊,一個是ClientViewController監聽的聊天請求收到了然後接受聊天進來此界面。

主動聊的話知道了對方的IP需要先建立連接。
被動聊的就直接接收和發送聊天內容即可。

下面代碼解釋:
比如我有3臺電腦,IP分別是192.168.1.1,192.168.1.2 192.168.1.3。都運行這個demo。1.1是做服務來用,那就rootvc爲導航到ServerViewController,1.2,1.3是兩個客戶端,rootvc爲導航到ClientViewController
服務端端口:8888 客戶端:9999

ServerViewController:

//1創建服務端套接字
    serverSocket = [[AsyncSocket alloc] initWithDelegate:self];
    //2.監聽連接端口的客戶端
  [serverSocket acceptOnPort:8888 error:nil];


//監聽到有客戶端要連我
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket{
  //newSocket.connectedHost 即客戶端的IP
}

//從連接上客戶端開始 協議方法傳入的socket 都是監聽的時候創建的newSocket!而跟serverSocket無關
// newSocket 來維持服務端和每個客戶端的連接 newSocket釋放了那麼服務端和相應的客戶端就斷開了 newSocket保存客戶端的主機和端口相關信息

//調用完監聽後會調用連接
//已經和客戶端建立連接
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    NSLog(@"服務端已經和客戶端:%@ 建立連接",host);
    //等待 sock 對應的客戶端的數據
    [sock readDataWithTimeout:-1 tag:101];
}

//接收到客戶端發來數據
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//把客戶端想得到的IP列表發過去
//writeData:withTimeout:tag:
//等待下次接收數據
 [sock readDataWithTimeout:-1 tag:102];
}

//發送數據成功
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

ClientViewController:

  • 發給服務端一個消息,然後拿到ip列表

    1. connectToHost:創建一個clientSocket,
      [_clientSocket connectToHost:@”192.168.1.1”
      onPort:8888 withTimeout:60 error:nil];
      ( 然後服務端就會走到didAcceptNewSocket, didConnectToHost:clienthost)

    2. didConnectToHost:客戶端和服務端連接成功,此方法裏調用readDataWithTimeout等待接收數據

    3. 如何拿到所有連接客戶端的IP:發個空消息到服務端(writeData:withTimeout:tag:)

    4. didWriteDataWithTag:消息發送成功。(服務端會走到didReadData然後給客戶端發消息)

    5. didReadData:拿到服務端發來的數據即所有連接了服務端的客戶端IP,顯示在tableview上

  • 監聽聊天請求(監聽連接此客戶端的其他客戶端)

    1. 創建一個新的socket叫listenSocket, [_listenSocket acceptOnPort:9999 error:nil]; 來監聽連接本機9999端口的請求。
    2. 監聽到了 didAcceptNewSocket, didConnectToHost
      彈框選擇接收聊天請求不,接受的話把newSocket傳過去

ChatViewController:
主動聊天已知對方ip,ip在列表上顯示着。
主動找人聊: alloc一個socket取名chatsocket,connectToHost:對方ip。

被動聊天因爲已經有了chatsocket(由ClientViewController的didAcceptNewSocket的newSocket傳來),直接readDataWithTimeout,writeData,不需要再connectToHost。

總結:
ServerViewController
[_serverTcp acceptOnPort:8888 error:nil];//監聽有沒有人連接

ClientViewController
[_listenSocket acceptOnPort:9999 error:nil];//監聽socket 監聽有沒有人找你聊天
- (void)onSocket:(AsyncSocket )sock didAcceptNewSocket:(AsyncSocket )newSocket//這裏監聽到有人來找你聊天的話則
_tmpChatSocket = newSocket;

[_clientSocket connectToHost:@”192.168.101.58” onPort:8888 withTimeout:60 error:nil];//連接socket 連服務器 拿聊天的人的列表

chatViewController
chatSocket = _tmpChatSocket
不是空則表示被動聊天 已經連接上 直接read write即可
是空的話則self.chatSocket = [[AsyncSocket alloc] initWithDelegate:self]; 去連接
[self.chatSocket connectToHost:self.chatIp onPort:9999 withTimeout:-1 error:nil] 其中self.chatIp是你點擊的那個cell的人的ip

發佈了56 篇原創文章 · 獲贊 28 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章