iOS 即时通讯,简单socket网络编程一<socket 底层>
来源:互联网 发布:淘宝能开刻章店吗 编辑:程序博客网 时间:2024/06/17 01:54
本篇文章简单介绍一下iOS的socket即时通讯底层的实现。
<1>socket简单的本地服务器的搭建,大家可以参考博客http://www.jianshu.com/p/39a68332e19f 。
<2>iOS socket编程的底层是通过调用C语言的函数,并通过OC和C语言的桥接,通过输入输出流进行数据读写,进行及时通讯。下面是一个简单的socket网络编程的demo。
//// ViewController.m// SocketTest//// Created by fe on 16/9/4.// Copyright © 2016年 fe. All rights reserved.//#import "ViewController.h"@interface ViewController ()<NSStreamDelegate,UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource>@property(nonatomic,strong) NSInputStream *inputStream;@property(nonatomic,strong) NSOutputStream *outputStream;//拿到输入框文本,以便修改位置@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textFieldCounterbottom;//用于存放聊天内容的数组@property (nonatomic,strong) NSMutableArray *msgArry;@property (weak, nonatomic) IBOutlet UITableView *msgTableView;@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]; }#pragma mark - NSStreamDelegate-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{// NSStreamEventOpenCompleted = 1UL << 0,//输入输出流打开完成// NSStreamEventHasBytesAvailable = 1UL << 1,//有字节可读// NSStreamEventHasSpaceAvailable = 1UL << 2,//可以发送字节// NSStreamEventErrorOccurred = 1UL << 3,//链接出现了错误// NSStreamEventEndEncountered = 1UL << 4//结束 switch (eventCode) { case NSStreamEventOpenCompleted: NSLog(@"输入输出流打开完成"); break; case NSStreamEventHasBytesAvailable: NSLog(@"有字节可读"); [self readData]; break; case NSStreamEventHasSpaceAvailable: NSLog(@"可以发送字节"); break; case NSStreamEventErrorOccurred: NSLog(@"链接出现了错误"); break; case NSStreamEventEndEncountered: NSLog(@"结束"); //关闭输入输出流 [self.inputStream close]; [self.outputStream close]; //从主循环移除 [self.inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [self.outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; break; default: break; }}- (IBAction)connectToInternet:(id)sender { //1:建立连接 NSString *localHost = @"127.0.0.1";//本机地址 int port = 12345;//服务器端口 //定义c语言输入输出流 CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(localHost), port, &readStream, &writeStream); //把c语言的输入输出流转化为oc对象 self.inputStream = (__bridge NSInputStream *)readStream; self.outputStream = (__bridge NSOutputStream *)(writeStream); //设置输入输出流的代理 self.inputStream.delegate = self; self.outputStream.delegate = self; //把输入输出流添加到主运行循环 [self.inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [self.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //打开输入输出流 [self.inputStream open]; [self.outputStream open];}- (IBAction)login:(id)sender { //2:收发数据 //2.1:登陆 发送用户名和密码 这里我们只简单的发送一个用户名进行登陆 //如果登陆发送的数据格式为 “iam:zhengyanfneg” //如果发送消息发送的数据格式为 “msg:How are you” //登陆指令 NSString *loginStr = @"iam:zhengyanfeng"; //将字符串转化为data NSData *loginData = [loginStr dataUsingEncoding:NSUTF8StringEncoding]; [self.outputStream write:loginData.bytes maxLength:loginData.length]; }#pragma mark - 读取服务器返回的数据- (void)readData{ //建立数据缓冲区可以放1024个字节(字节数组) uint8_t buf[1024]; //length 返回的实际字节长度 NSInteger length =[self.inputStream read:buf maxLength:sizeof(buf)]; //把字节转化成字符串 NSData *receiveData =[NSData dataWithBytes:buf length:length]; NSString *receiveStr = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding]; [self reloadDataWithString:receiveStr]; }#pragma mark - UITextFieldDelegate- (BOOL)textFieldShouldReturn:(UITextField *)textField{ //发送聊天数据 NSString *mesStr = [NSString stringWithFormat:@"msg:%@",textField.text]; [self reloadDataWithString:mesStr]; NSData *strData = [mesStr dataUsingEncoding:NSUTF8StringEncoding]; [self.outputStream write:strData.bytes maxLength:strData.length]; 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{ [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
0 0
- iOS 即时通讯,简单socket网络编程一<socket 底层>
- iOS 即时通讯,简单socket网络编程二<socket 封装 - GCDAsyncSocket >
- IOS底层网络之Socket
- Socket网络编程 -iOS开发简单实例
- iOS socket网络编程
- Socket网络编程(一)
- Socket网络编程(一)
- iOS即时通讯 Socket
- 【IOS网络编程】socket编程
- socket网络编程(一):最简单的一收一发
- SOCKET网络编程(简单介绍)
- iOS中的Socket编程,Socket基础知识(一)
- ios网络编程(http、socket)
- iOS网络编程之Socket
- iOS网络编程之Socket
- iOS网络编程之Socket
- iOS网络编程之Socket
- ios网络编程(http、socket)
- 机器学习概述
- JAVA比较陷阱——易错点(包含自动装箱)
- 安卓源码编译--常见问题集
- 有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
- Linux内存管理原理
- iOS 即时通讯,简单socket网络编程一<socket 底层>
- 华为上机笔试 2016-9-4
- 欢迎大神们来挑刺(关于C51串口通信)
- OKHttp源码分析3 - HttpEngine底层实现
- Build.Gradle 文件解析
- spring整合struts2
- API文档使用方法
- 【hibernate】关联映射那些事(四)----继承映射
- PowerDesigner连接MySQL失败的解决方式