iOS 即时通讯,简单socket网络编程二<socket 封装 - GCDAsyncSocket >
2016-09-09 16:11
309 查看
在socket编程中,如果直接调用C语言函数的CFReadStreamRef(输入流)和CFWriteStreamRef(输出流)进行收发数据就会非常繁琐,于是就出现了第三方库GCDAsyncSocket对C语言进行了封装。这样我们就可以直接面对socket对象进行即时通讯。下面是使用GCDAsyncSocket写的一个简单的连接登陆服务器,并简单通信的Demo,服务器的搭建可以参考博客http://www.jianshu.com/p/39a68332e19f
。
。
// // ViewController.m // SocketTest // // Created by fe on 16/9/4. // Copyright © 2016年 fe. All rights reserved. // #import "ViewController.h" #import "GCDAsyncSocket.h" @interface ViewController ()<UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource,GCDAsyncSocketDelegate> //拿到输入框文本,以便修改位置 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textFieldCounterbottom; //用于存放聊天内容的数组 @property (nonatomic,strong) NSMutableArray *msgArry; @property (weak, nonatomic) IBOutlet UITableView *msgTableView; //socket 对象 @property (nonatomic,strong) GCDAsyncSocket *socket; @end @implementation ViewController - (NSMutableArray *)msgArry { if (!_msgArry) { _msgArry = [[NSMutableArray alloc] init]; } return _msgArry; } - (void)viewDidLoad { [super viewDidLoad]; //监听键盘 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(theKeyBoardDidChanged:) name:UIKeyboardWillChangeFrameNotification object:nil]; } - (IBAction)connectToInternet:(id)sender { //1:建立连接 NSString *localHost = @"127.0.0.1";//本机地址 int port = 12345;//服务器端口 self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; [self.socket connectToHost:localHost onPort:port error:nil]; } #pragma mark -GCDAsyncSocketDelegate -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { NSLog(@"GCDAsyncSocketDelegate链接服务器成功"); } -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { NSLog(@"GCDAsyncSocket服务器连接失败"); } -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSString *recData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if (tag == 102) {//服务器返回的聊天数据需要展示到表格上 [self reloadDataWithString:recData]; }else if (tag == 101){//登陆返回的数据不需要展示在表格 } } -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { NSLog(@"数据成功发送到服务器"); //数据发送成功后,自己调用一下读取数据的方法,接着socket才会调用读取数据的代理方法 [self.socket readDataWithTimeout:-1 tag:tag]; } - (IBAction)login:(id)sender { //2:收发数据 //2.1:登陆 发送用户名和密码 这里我们只简单的发送一个用户名进行登陆 //如果登陆发送的数据格式为 “iam:zhengyanfneg” //如果发送消息发送的数据格式为 “msg:How are you” //登陆指令 NSString *loginStr = @"iam:zhengyanfeng"; //将字符串转化为data NSData *loginData = [loginStr dataUsingEncoding:NSUTF8StringEncoding]; [self.socket writeData:loginData withTimeout:-1 tag:101]; } #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { //发送聊天数据 NSString *mesStr = [NSString stringWithFormat:@"msg:%@",textField.text]; [self reloadDataWithString:mesStr]; NSData *strData = [mesStr dataUsingEncoding:NSUTF8StringEncoding]; [self.socket writeData:strData withTimeout:-1 tag:102]; textField.text = nil; return YES; } //监听键盘位置变化的方法 - (void)theKeyBoardDidChanged:(NSNotification *)noti{ NSLog(@"%@",noti.userInfo); CGFloat windowH = [UIScreen mainScreen].bounds.size.height; CGRect keyboardFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGFloat keyboardY = keyboardFrame.origin.y; self.textFieldCounterbottom.constant = windowH - keyboardY; } #pragma mark - UITableViewDelegate UITableViewDataSource -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.msgArry.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *const reuseID = @"socketCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseID]; cell.textLabel.text = self.msgArry[indexPath.row]; return cell; } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [self.view endEditing:YES]; } //向聊天数组添加数据并刷新表格 - (void)reloadDataWithString:(NSString *)msgStr { dispatch_async(dispatch_get_main_queue(), ^{ [self.msgArry addObject:msgStr]; [self.msgTableView reloadData]; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(self.msgArry.count -1 ) inSection:0]; [self.msgTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; }); } @end
相关文章推荐
- TCP/UDP协议的Socket编程(Java语言)
- python 使用socket模拟tcp客户端和tcp服务器端
- IOSApp Transport Security has blocked a cleartext HTTP (http://) resource load的解决办法
- 显示网络请求的文本需要从 GBK 转到 UTF-8 Ios
- python打开网络图片并缩放
- http get post put delete 区别
- 从网络端leanCloud获取上传的图片和文字并以listview的形式显示在android端
- 安装Flume的时候出现File Channel transaction capacity cannot be greater than the capacity of the channel capacity -解决方案 摘自网络
- C++网络框架和库
- 通过HTTP post方法请求资源可以带查询字符串吗?
- 网络爬虫(密码破解)
- 三大WEB服务器(apache lighttpd nginx) 对比分析
- python 使用socket、multiprocessing、re模块,模拟简易HTTP服务器
- 数据中心网络高可用架构
- 关于Retrofit的理解之Hello Retrofit
- 不需要下载图片 获取网络图片大小
- 【TCP/Ip】为什么局域网的IP普遍是192.168开头?
- postgresql利用openssl实现网络数据传输加密 3ff8
- http状态码代表含义
- iOS之网络请求之AFN表单上传之form-data