利用AsyncSocket来实现客户端与服务端,客户端与客户端的通信

时间:2022-09-20 19:35:49

作者: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。