用C的输入输出流 简单实现即时通讯
2017-08-16 00:00
253 查看
一、首先搭建一个简单的服务器
Python服务器代码下载:
python服务器:链接: https://pan.baidu.com/s/1hsd3ZYO 密码: gyxg其中已包含了下文需要安装的 zope.interface 和 twisted 两个文件,免去了你再去官网下载。
ps:该源码只能在python2运行环境成功执行,python3虽然能连接但是无法发送数据。
查看python版本方法,直接在命令行输入python
启动服务器的方法:
1.打开终端,用cd 命令进到chatserver.py这个文件所在的路劲。2.输入python chatserver.py
如果报了这个没有twisted这个错误的话,那就要安装一下了。
安装方法:
1.安装twisted. 需要先安装zope.interface,才能安装twisted.
下载地址:https://pypi.python.org/pypi/zope.interface (上面已提供,不用下载了)下载后你会得到一个
的压缩包,
解压后的文件目录为:
然后在终端先进入这个名为zope.interface-4.1.3的文件夹路径,然后输入sudo python setup.py install 接着要求输入一下电脑密码,便可以安装zope.interface。
2.安装twisted
下载地址:https://twistedmatrix.com/trac/wiki/Downloads (上面已提供,不用下载了)解压后目录:
安装方法和上面一样,sudo python setup.py install 接着输入一下电脑密码,便可以安装twisted。
验证twisted是否安装成功
①先输入python 回车
②输入import twisted 回车 没有任何提示,说明twisted安装成功了
现在,再次启动服务器试试:
启动成功啦。
二、编写客户端代码
1.搭建简易UI2.编写 连接服务器 的BarButtonItem 方法:
//1.连接服务器 - (IBAction)connect:(id)sender { //建立连接 NSString *host = @"127.0.0.1"; int port = 12345; //定义输入输出流 CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream); //把C语言的输入输出流转化成OC对象 _inputStream = (__bridge NSInputStream *)(readStream); _outputStream = (__bridge NSOutputStream *)(writeStream); //设置代理 监听连接成功情况 _inputStream.delegate = self; _outputStream.delegate = self; //把输入输出流添加到主运行循环(不添加主运行循环,代理可能不工作) [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //打开输入输出流 [_inputStream open]; [_outputStream open]; }
3.编写代理方法:(当上一步的 连接服务器 操作成功后,会走下面的代理方法,打印输入输出流打开完成 和 可以发送字节, 该方法会在多种情况下调用,具体看下面的枚举说明)
//代理方法 -(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{ NSLog(@"%@",aStream); /* 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(@"连接结束"); //关闭输入流 [_inputStream close]; [_outputStream class]; //从主运行循环移除 [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; break; default: break; } }
读取数据库返回的数据 方法
//读取服务器返回的数据 -(void)readData{ //建立缓冲区,即:创建一个可以放1024个字节 的字节数组 uint8_t buf[1024]; //返回时间装的字节数 NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)]; //把字节数组转化成字符串 ,把len的长度的字符 放到buf中 NSData *data = [NSData dataWithBytes:buf length:len]; //从服务器接收到的数据 NSString *recStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@",recStr); }
4.编写登录方法 (登录方法中,我们有做发送数据给服务器,一旦登录成功了,服务器会给出响应数据的,因此会调用 第3步骤的代理方法,控制台打印服务器有返回字节)
//2.登录 (会发送用户名给服务器) - (IBAction)login:(id)sender { //发送用户名和密码(我这里只发了用户名,没有密码) /* 服务器规定: 如果要登录,发送的数据格式为:"iam:zhangsan"; 如果要发送聊天消息,数据格式为:"msg:did you have dinner"; */ //登录指令 NSString *loginStr = @"iam:zhangsan"; //把NSString 转成 NSdata NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding]; //第一个参数(nonnull const uint8_t *) :要求传一个uint8 * 类型的参数,这或其实就是unsigned char * [_outputStream write:data.bytes maxLength:data.length]; }
5.编写发送数据方法
//点击键盘上的return 发送消息 -(BOOL)textFieldShouldReturn:(UITextField *)textField{ NSString *text = textField.text; NSLog(@"%@",text); //聊天消息 NSString *msgStr = [NSString stringWithFormat:@"msg:%@",text]; //把NSString 转成 NSdata NSData *data = [msgStr dataUsingEncoding:NSUTF8StringEncoding]; //第一个参数(nonnull const uint8_t *) :要求传一个uint8 * 类型的参数,这或其实就是unsigned char * [_outputStream write:data.bytes maxLength:data.length]; return YES; }
到此为止就完成了用输入输出流写了一个简单的即时通讯的例子。
演示:
1.点击连接服务器按钮:控制台打印如下,可以看到输入输出流分别打开,并且可以发送字节
2.点击登录按钮:控制台打印如下,可以看到服务器返回了zhangsan has joined
3.在TextField中输入要发送的内容,然后点击键盘上的return。 可以看到命令行中出现了qwer,我们客户端的内容传到了服务器了。
相关文章推荐
- C语言写的简单贪吃蛇程序,实现WASD控制蛇运动,输入输出流为C++
- OC原生的输入输出流结合socket实现即时通讯
- 数组例子2:二维数组中的行列互换和按钮控件数组实现计算器界面(暂不支持计算功能,仅界面及简单输入)
- jQuery实现简单的日期输入格式化控件
- 一个简单的利用ini配置文件以及用户输入的交互进行文件夹内容拷贝的批处理文件脚本的实现
- C语言实现的简单银行存取款程序 请输入如下数字命令
- Java用字节输入输出流实现从一个文件到另一个文件的内容追加
- java websocket实现简单的即时通讯 消息推送
- 从头认识Spring-3.4 简单的AOP日志实现-扩展添加检查订单功能,以便记录并检測输入的參数
- EditText中输入密码可见的简单实现
- 多线程同步锁实现简单数据的同步输入与输出
- comet(http 请求长连接) 之 ajax 长查询 简单实现。 (webim 即时通讯)
- 基础学习:控制台接收输入字符与重定向输出流实现程序日志两例子的编程
- 重定向输出流简单实现程序日志
- python实现简单的用户密码登录控制(输入三次就锁定用户)
- 文件输入输出流的简单用法
- java 输入输出流和File简单解析(附android中文乱码问题解决)
- C++的输入输出流简单总结【字符串】
- JS_简单实现页面输入
- C#设置textBox只能输入数字(正数,负数,小数)简单实现