iOS之NSStream聊天室

Swift

//
//  ViewController.swift
//  stocket
//
//  Created by ling on 16/1/4.
//  Copyright © 2016年 ling. All rights reserved.
//

import UIKit

class ViewController: UIViewController,NSStreamDelegate {
    
    
    var inputStream:NSInputStream?
    var outputSteam:NSOutputStream?
    
    var incomingDataBuffer =  NSMutableData()
    var outgoingDataBuffer =  NSMutableData()
    

    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
    //1、代理方法
    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
     //   print("%@",NSThread.currentThread())
        
        switch eventCode {
        
        case  NSStreamEvent.OpenCompleted:
            print("輸入輸出流打開完成")
        case  NSStreamEvent.HasBytesAvailable:
            print("有字節可讀")
            self.readData()
        case  NSStreamEvent.HasSpaceAvailable:
            print("能夠發送字節")
        case  NSStreamEvent.ErrorOccurred:
            print("鏈接出現錯誤")
        case  NSStreamEvent.EndEncountered:
            print("鏈接結束")
        
            //關閉輸入輸出流
            inputStream?.close()
            outputSteam?.close()
            
            //從主運行循環移除
            inputStream?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
            outputSteam?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
            
        default:
            break
        
    }
        
    }
    
    //2、連接服務器
    @IBAction func linkBtn(sender: UIButton) {
        
        //1.創建鏈接
        let host:CFString = "127.0.0.1"
        let port:UInt32 = 8004
        
        //定義C語言輸入輸出流
        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?
        
        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,host, port, &readStream, &writeStream);
        
        //把C語言的輸入輸出流轉換成swift對象
        self.inputStream = readStream!.takeUnretainedValue()
        self.outputSteam = writeStream?.takeUnretainedValue()
        
        //設置代理
        self.inputStream?.delegate = self
        self.outputSteam?.delegate = self
        
        //把輸入輸出流添加到主循環
        self.inputStream?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        self.outputSteam?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        
        //打開輸入輸出流
        self.inputStream?.open()
        self.outputSteam?.open()
        
    }
    
    //3、登陸
    @IBAction func loginBtn(sender: UIButton) {
        
        //登陸指令
        let loginStr = "iam:ling"
        
        //Str轉成NSData
        let data = loginStr.dataUsingEncoding(NSUTF8StringEncoding)
        
        //NSData轉爲NSMutableData
        self.outgoingDataBuffer.appendData(data!)

        let readBytes = self.outgoingDataBuffer.mutableBytes
        
        let len = self.outgoingDataBuffer.length

        let buf = UnsafeMutablePointer<UInt8>.alloc(len)
        memcpy(buf, readBytes, len)
        
        self.outputSteam?.write(buf, maxLength: len)
    }
    
    //4、讀取服務器返回數據
    let maxBuff = 1024
    func readData(){
        
        //創建一個緩衝區,能夠放1024個字節
        let buf = UnsafeMutablePointer<UInt8>.alloc(maxBuff)
      
        //返回實際裝的字節數
        let len = self.inputStream!.read(buf, maxLength: maxBuff)
        
        //把字節數組轉化成字符串
        let data = NSData(bytes: buf, length: len)
        
        //從服務器接收到的數據
        let recStr = NSString.init(data: data, encoding: NSUTF8StringEncoding)
        
        print(recStr)
    }
    
    
    }


Objective-C

//
//  ViewController.m
//  StocketAndOC
//
//  Created by ling on 16/1/5.
//  Copyright © 2016年 ling. All rights reserved.
//

#import "ViewController.h"

@interface ViewController () <NSStreamDelegate>{
    NSInputStream *_inputStream;
    NSOutputStream *_outputStream;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

//1.代理方法
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    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 close];
            
            // 從主運行循環移除
            [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
            [_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
            break;
        default:
            break;
    }
}

- (IBAction)linkBtn:(UIButton *)sender {
    
    // 1.創建鏈接
    NSString *host = @"127.0.0.1";
    int port = 8004;
    
    // 定義C語言輸入輸出流
    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];

}


- (IBAction)loginBtn:(UIButton *)sender {
    
    //登陸的指令
    NSString *loginStr = @"iam:zhangsan";
    
    //把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 *recStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@"%@",recStr);

    
}
@end
相關文章
相關標籤/搜索