IOS GCDAsyncSocket

//
//  ViewController.m
//  05.聊天室
//
//  Created by apple on 14/12/5.
//  Copyright (c) 2014年 heima. All rights reserved.
//

#import "ViewController.h"
#import "GCDAsyncSocket.h"

@interface ViewController ()<UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate,GCDAsyncSocketDelegate>{

    GCDAsyncSocket *_socket;
}
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewConstraint;
@property (weak, nonatomic) IBOutlet UITableView *tableView;

@property (nonatomic, strong) NSMutableArray *chatMsgs;//聊天消息数组

@end

@implementation ViewController

-(NSMutableArray *)chatMsgs{
    if (!_chatMsgs) {
        _chatMsgs = [NSMutableArray array];
    }

    return _chatMsgs;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // 2.收发数据
    // 做一个聊天
    // 1.用户登录
    // 2.收发数据

    // 监听键盘
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbFrmWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

-(void)kbFrmWillChange:(NSNotification *)noti{
    NSLog(@"%@",noti.userInfo);

    // 获取窗口的高度

    CGFloat windowH = [UIScreen mainScreen].bounds.size.height;

    // 键盘结束的Frm
    CGRect kbEndFrm = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
     // 获取键盘结束的y值
    CGFloat kbEndY = kbEndFrm.origin.y;

    self.inputViewConstraint.constant = windowH - kbEndY;
}

- (IBAction)connectToHost:(id)sender {
    // 1.建立连接
    NSString *host = @"127.0.0.1";
    int port = 12345;

    // 创建一个Socket对象
    _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

    // 连接
    NSError *error = nil;
    [_socket connectToHost:host onPort:port error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
}

#pragma mark -AsyncSocket的代理
#pragma mark 连接主机成功
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    NSLog(@"连接主机成功");
}

#pragma mark 与主机断开连接
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{

    if(err){
        NSLog(@"断开连接 %@",err);
    }
}

- (IBAction)loginBtnClick:(id)sender {

    // 登录
    // 发送用户名和密码
    // 在这里做的时候,只发用户名,密码就不用发送

    // 如果要登录,发送的数据格式为 "iam:zhangsan";
    // 如果要发送聊天消息,数据格式为 "msg:did you have dinner";

    //登录的指令
    NSString *loginStr = @"iam:zhangsan";

    //把Str转成NSData
    NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];

    //[_outputStream write:data.bytes maxLength:data.length];
    // 发送登录指令给服务
    [_socket writeData:data withTimeout:-1 tag:101];
}

#pragma mark 数据成功发送到服务器
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
    NSLog(@"数据成功发送到服务器");
    //数据发送成功后,自己调用一下读取数据的方法,接着_socket才会调用下面的代理方法
    [_socket readDataWithTimeout:-1 tag:tag];
}

#pragma mark 服务器有数据,会调用这个方法
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    // 从服务器接收到的数据
    NSString *recStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"%@ %ld %@",[NSThread currentThread],tag, recStr);

    if (tag == 102) {//聊天返回的数据
        // 刷新表格
        [self reloadDataWithText:recStr];
    }
//    }else if(tag == 101 ){//登录返回数据,不应该把数据添加到表格里
//
//
//    }

}

-(BOOL)textFieldShouldReturn:(UITextField *)textField{

    NSString *text = textField.text;

    NSLog(@"%@",text);
    // 聊天信息
    NSString *msgStr = [NSString stringWithFormat:@"msg:%@",text];

    //把Str转成NSData
    NSData *data = [msgStr dataUsingEncoding:NSUTF8StringEncoding];

    // 刷新表格
    [self reloadDataWithText:msgStr];

    // 发送数据
    [_socket writeData:data withTimeout:-1 tag:102];

    // 发送完数据,清空textField
    textField.text = nil;

    return YES;
}

-(void)reloadDataWithText:(NSString *)text{
    [self.chatMsgs addObject:text];

    // UI刷新要主线程
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];

        // 数据多,应该往上滚动
        NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count - 1 inSection:0];
        [self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    });

}

#pragma mark 表格的数据源

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.chatMsgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    cell.textLabel.text = self.chatMsgs[indexPath.row];

    return cell;
}

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self.view endEditing:YES];
}
@end
时间: 2024-08-02 20:21:53

IOS GCDAsyncSocket的相关文章

GCDAsyncSocket类库,IOS下TCP通讯使用心得

关于在IOS下使用Socket进行通讯的技术文章也许诺很久了,今日又是一个还债的日子,网上虽然很多介绍过AsyncSocket或GCDAsyncSocket的文章,但其实就那么一两篇大部分都是转载,于是我义正言辞.慷慨激昂的批判他们这种不负责任的态度,学习,不是给自己学的,是要和大家分享的.技术的共享有利于整体行业的进步,也可以使自身更深入全面的了解. 之前的文章中我们讲到过TCP通讯协议,并且也对其进行了较为详细的介绍和描述,关于TCP通讯的原理此处我们不再赘述,如有需要的看官可自行翻阅本人所

iOS开发——GCDAsyncSocket

新进的这家公司搞智能家居,就随便整理一下其相关技术吧!首先,从GCDAsyncSocket的使用问题着手. 正如名称一样GCDAsyncSocket开源类库是以苹果的GCD多任务处理机制完成的一个异步交互套接字通讯.使用方法其实并不复杂.每一个GCDAsyncSocket对象(以下简称GCDSocket对象)都可以理解为一个socket套接字,我们的操作都是针对于这个socket执行的各种命令,可以打开一个端口侦听,同样也可以连接其他计算机的端口进行数据通讯等等等等. 首先我们来创建一个sock

iOS Socket/Tcp编程 GCDAsyncSocket的实战(带回调)

很多同学一听到Socket TCP UDP 这几个字眼感觉特别害怕,很怕在工作当中使用,因为他们太底层了.下面我把我在工作中使用Socket类库GCDAsyncSocket进行一次实战 文章中只适用于小型数据传输, 如果比较到,例如音频文件的话,请自行拼接data. 首先向工程导入GCDAsyncSocket.h/GCDAsyncSocket.m 下载地址:链接:http://pan.baidu.com/s/1c1bHytM密码: p22g 然后创建一个单例类Client 继承于NSObject

iOS开发——网络编程OC篇&amp;GCDAsyncSocket编程

GCDAsyncSocket编程 同上一篇文章一样,这里也是使用Socket实现一个聊天室,但是这里使用的是一个常用的框架实现的:GCDAsyncSocket 一:导入这个框架 二:声明这个Socket的成员变量,定义一个消息数组 1 @interface ViewController ()<UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate,GCDAsyncSocketDelegate>{ 2 3 GCDAsyncSoc

iOS之GCDAsyncSocket第三方库的使用

Socket描述了一个IP.端口对.它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息.所以,Socket一定包含了通信的双发,即客户端(Client)与服务端(server). 1)服务端利用Socket监听端口: 2)客户端发起连接: 3)服务端返回信息,建立连接,开始通信: 4)客户端,服务端断开连接. 1套接字(socket)概念 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元. 应用层通过传输层进行

自己总结的 iOS ,Mac 开源项目以及库,知识点------持续更新

自己在 git  上看到一个非常好的总结的东西,但是呢, fork  了几次,就是 fork  不到我的 git 上,干脆复制进去,但是,也是认真去每一个每一个去认真看了,并且也是补充了一些,感觉非常棒,所以好东西要分享,为啥用 CN 博客,有个好处,可以随时修改,可以持续更新,不用每次都要再发表,感觉这样棒棒的 我们 自己总结的iOS.mac开源项目及库,持续更新.... github排名 https://github.com/trending,github搜索:https://github.

Objective C (iOS) for Qt C++ Developers(iOS开发,Qt开发人员需要了解什么?)

Qt/C++开发人员眼中的Obj-C 对于我们第一次自己定义iOS应用来说,对于来自Qt/C++开发人员来说,我不得不学习Objective-C相关语法与知识 为了让读者可以更easy理解这篇博客的内容,我将描写叙述诸多我所学到的东西.这将很多其它的是大脑转存而不是单一的教程 ,所以我仍然希望这将对你非常有帮助,我将首先写编程语言的差异,然后再写关于类库的差异 1.Objective C vs C vs C++ 类似于C++,Obj-c是C语言的一个超集(这不是100%正确的,可是一个足够好的语

iOS 即时通讯,从入门到 “放弃”?

原文链接:http://www.jianshu.com/p/2dbb360886a8 本文会用实例的方式,将 iOS 各种 IM 的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. —— 由宇朋Look分享 前言 本文会用实例的方式,将iOS各种IM的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. 注:文中的所有的代码示例,在github中都有demo:iOS即时通讯,从入门到“放弃”?(demo)可以打开项目先预览效果,对照着进行阅读. 言归正传,首先我们来总

iOS、mac开源项目及库汇总

UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明.具体使用看“使用方法”. (国人写) XHRefreshControl – XHRefreshControl 是一款高扩展性.低耦合度的下拉刷新.上提加载更多的组件.(国人写) CBStoreHou