XMPP框架 微信项目开发之Socket聊天室的建立与登录

Socket就是为网络服务提供的一种机制。

通信的两端都是Socket

网络通信其实就是Socket间的通信。

数据在两个Socket之间通过IO传输。

Socket服务器有两种一种是类似于QQ的服务器,另一种就是网站服务器。所谓服务器就是提供资源访问的。网站服务器是短连接。聊天室是长连接。

所谓的短连接比如访问网址时便会返回网站数据,返回数据后就会关闭连接。

但是长连接一旦建立连接就会一直监听数据的发送与接收,不会关闭连接。

所谓的IO就是输入输出流。输出流:用来写数据(发送数据)。 输入流:用于读数据(接收数据)。

在工程的网络连接中会有很多C语言与OC类型数据进行转换的操作,转换的技巧如下:保存,点击错误提示的红色圆点,会出现修正提示,点击第一项bridge桥接即可自动进行类型转换。

Socket聊天室的大致原理过程如下:






因为内容繁多,只在代码内做注释,不再剖析方法的使用。

新建工程,具体如下:

第一步:打开聊天室服务器文件


第二步:查看服务器文件的内容(端口号,以及数据发送格式)。



第三步:进行界面搭建

3.1


3.2


3.3


3.4


3.5


3.6


3.7


viewController视图控制器的代码如下:

//
//  ViewController.m
//  聊天室
//
//  Created by apple on 15/11/4.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()<NSStreamDelegate>
{
    NSInputStream *_inputStream;  // 对应输入流
    NSOutputStream *_outputStream; // 对应输出流
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    //  收发数据
    // 做一个聊天
    // 1. 用户登录
    // 2. 登录成功后即可收发数据
}

-(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(@"连接结束");
            break;
        default :
            break;
    }
}
- (IBAction)connectToHost:(id)sender {
    // 1. 第一步建立连接
    /*  点击参数——>在编辑界面右侧就有此参数的描述
     第一个参数CFAllocatorRef alloc:用于为输入输出流分配空间,如果传为NULL就会使用默认的大小分配
     第二个参数CFStringRef host:所要连接到主机的IP地址。即要连接到哪台主机。
     第三个参数port:所要连接到主机的具体端口号。
     */
    NSString *host = @"127.0.0.1"; // 因为是C语言函数所以要进行桥接转换为C语言字符串
    int port = 12345;
    // 定义输入输出流
    CFReadStreamRef  readStream;
    CFWriteStreamRef  writeStream;
    CFStreamCreatePairWithSocketToHost(NULL,  (__bridge CFStringRef)(host), port, &readStream, &writeStream);
    
    // 将C语言的输入输出流转化为OC对象
    // 如果要想知道连接成功还是失败,可以通过OC中的代理进行实现。所以需要将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];
    
}
- (IBAction)loginBtnClick:(id)sender {
    
    // 登录
    // 发送用户名和密码
    // 在这里做的时候,只发用户名,密码就不用发送
    
    // 如果要登录,发送的数据格式为 "iam:zhangsan"
    // 如果要发送聊天消息,数据格式为"msg:did you have dinner"
    //    uint8_t typedef —> unsigned char uint8_t;
    //   (const uint8_t *) 意味着要传入一个字节数组
    //  maxLength: 表示发送字节数组中的前多少个字节
    
    // 登录的指令
    NSString *loginStr = @"iam:zhangsanXXXXXXX";
    
    // 把Str转化为NSData
    NSData  *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];
    
    [_outputStream write:data.bytes maxLength:data.length];
    
}

#pragma mark - 读取服服务器返回的数据
-(void)readData
{
    // 建立缓冲区,可以存放1024个字节
    uint8_t buf[1024];
    
    // 返回实际装的字节
    NSInteger  len =  [_inputStream read:buf maxLength:sizeof(buf)];
    
    // 把字节数组转化为字符串
    NSData *data = [NSData dataWithBytes:buf length:len];
    
    // 从服务器接收到的数据
    NSString *reciveStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@"%@", reciveStr);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
运行结果如下:



相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页