您的位置:首页 > 理论基础 > 计算机网络

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: