python服务器:连接: https://pan.baidu.com/s/1hsd3ZYO 密码: gyxgpython
其中已包含了下文须要安装的 zope.interface 和 twisted 两个文件,免去了你再去官网下载。数据库
ps:该源码只能在python2运行环境成功执行,python3虽然能链接可是没法发送数据。数组
查看python版本方法,直接在命令行输入python服务器
1.打开终端,用cd 命令进到chatserver.py这个文件所在的路劲。 oop
2.输入python chatserver.py ui
若是报了这个没有twisted这个错误的话,那就要安装一下了。spa
下载地址:https://pypi.python.org/pypi/zope.interface (上面已提供,不用下载了)命令行
下载后你会获得一个的压缩包,代理
解压后的文件目录为:code
而后在终端先进入这个名为zope.interface-4.1.3的文件夹路径,而后输入sudo python setup.py install 接着要求输入一下电脑密码,即可以安装zope.interface。
下载地址:https://twistedmatrix.com/trac/wiki/Downloads (上面已提供,不用下载了)
解压后目录:
安装方法和上面同样,sudo python setup.py install 接着输入一下电脑密码,即可以安装twisted。
①先输入python 回车
②输入import twisted 回车 没有任何提示,说明twisted安装成功了
启动成功啦。
1.搭建简易UI
2.编写 链接服务器 的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,咱们客户端的内容传到了服务器了。