iOS 网络通信04

一、客户端

  1. 链接到服务器

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.链接到服务器
    //1.1 创建一个客户端socket
    GCDAsyncSocket *clientSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    self.clientSocket = clientSocket;
    //1.2 发送连接请求
    NSError *erro = nil;
    [clientSocket connectToHost:@"172.21.62.9" onPort:5288 error:&erro];
    if (!erro) {
        NSLog(@"%@",erro);
    }
    //2.发送聊天消息和接收消息
}

  2.通过代理方法,查看链接状态

#pragma mark -- 与服务器链接成功
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    NSLog(@"与服务器链接成功");
    //接收数据的前提是  要监听
    [sock readDataWithTimeout:-1 tag:0];
}
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"与服务器断开链接%@",err);
}

  3.通过代理方法,读取服务器端的消息

//读取服务器端的消息
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"===%@",str);
    NSLog(@"%@",[NSThread currentThread]);
    if (str) {
        [self.dataSources addObject:str];
        //刷新表格 回到主队列
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
            NSLog(@"%@",[NSThread currentThread]);
        });
//      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
//            [self.tableView reloadData];
//        }];
    }
    //读完数据的前提是  要监听
    [sock readDataWithTimeout:-1 tag:0];
}

  4.客户端界面的消息

//客户端界面发送消息
- (IBAction)didSendButton:(id)sender {
    NSString *str = self.textField.text;
    if (str.length == 0) {
        return;
    }
    //把数据添加到数据源里边
    [self.dataSources addObject:str];
    //刷新表格
//    dispatch_async(dispatch_get_main_queue(), ^{
//        [self.tableView reloadData];
//    });
    [self.tableView reloadData];
    //发送数据
    [self.clientSocket writeData:[str dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}

  5.通过tableView的cell对数据进行显示 

#pragma mark -- tableView代理方法  表格数据源
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataSources.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *ID = @"CELL";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:ID];
    }
    //显示文字
    cell.textLabel.text = self.dataSources[indexPath.row];
    return cell;
}

二、服务器端

  1.开启服务器

/**
 *  开启10086服务 端口:5288
 */
-(void)start{
   //创建一个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(@"服务开启成功");
    }else{
        NSLog(@"服务器开启失败:%@",error);
    }
    self.serverSocket = serverSocket;
}

  2.链接客户端的Socket

#pragma mark -- 有客户端Socket连接到服务器
-(void)socket:(GCDAsyncSocket *)serverSocket didAcceptNewSocket:(GCDAsyncSocket *)clientSocket{

    NSLog(@"serve:%@",serverSocket);
    NSLog(@"client:%@ host:%@,port:%d",clientSocket,clientSocket.connectedHost,clientSocket.connectedPort);
    //1.保存客户端的Socket
    [self.clientSockets addObject:clientSocket];
    
    //2.监听客户端是否有数据上传
    [clientSocket readDataWithTimeout:-1 tag:0];

    NSLog(@"当前有几个%ld客户连接到服务器",self.clientSockets.count);
}

  3.读取客户请求的数据

#pragma mark -- 读取客户请求的数据
-(void)socket:(GCDAsyncSocket *)clientSocket didReadData:(NSData *)data withTag:(long)tag{
    //核心代码
    for (GCDAsyncSocket *socket in self.clientSockets) {
        if (socket != clientSocket) {//判断不要发给自己
            [socket writeData:data withTimeout:-1 tag:0];
        }
    }
#warning 每次读完数据后,都要用一次监听数据的方法
    [clientSocket readDataWithTimeout:-1 tag:0]; 
}

你可能感兴趣的:(群聊)