zoukankan      html  css  js  c++  java
  • iOS 基于Socket 的 C/S 网络通信结构(下一个)

                 以前实现简单 Server 程序,服务端通过 void WriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void* clientCallBackInfo) 函数向client发送“你好。client!”的消息,假设client接收成功的话就会显示“你好。client!

    ”。须要显示服务端发送过来的消息。那么就须要定义一个UILabel输出口(IBOutlet)来显示消息;client还须要加入两个button,一个用来接收服务端消息的动作事件方法 receiveData:和发送client“收到啦,服务端”消息的动作事件方法 sendData:;加入关联就能够了,比較简单,以下来看一下详细实现的代码:

         ViewController.h

    #import <UIKit/UIKit.h>
    
    #import <CoreFoundation/CoreFoundation.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #define PORT 8734       //将端口设置为8734。能够依据详细情况改变
    
    @interface ViewController : UIViewController<NSStreamDelegate>
    {
        int flag ; //操作标志 0为发送 1为接收
    }
    
    @property (nonatomic, retain) NSInputStream *inputStream;
    @property (nonatomic, retain) NSOutputStream *outputStream;
    
    @property (weak, nonatomic) IBOutlet UILabel *message;    //在client显示来自服务端的消息
    
    - (IBAction)sendData:(id)sender;      //发送client的消息
    - (IBAction)receiveData:(id)sender;   //接收来自服务端的消息
    
    @end
          ViewController.m

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }
    
    //初始化client网络连接
    - (void)initNetworkCommunication
    {
        
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        //这里须要填写 IP 地址,依据自己路由能够用的 IP来定,这里是192.168.1.103,假设不知道能够下载 IP 扫描器
        CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.1.103", PORT, &readStream, &writeStream);
        
        self.inputStream = (__bridge_transfer NSInputStream *)readStream;  //将CFStream对象转化为NSStream对象
        self.outputStream = (__bridge_transfer NSOutputStream
                         *)writeStream;              //将CFStream对象转化为NSStream对象
        [self.inputStream setDelegate:self];
        [self.outputStream setDelegate:self];
        [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];    //NSStream 方法 scheduleInRunLoop: 设置 Run Loop
        [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                 forMode:NSDefaultRunLoopMode];
        [self.inputStream open];   //NSStream 的 open 方法来打开数据流对象
        [self.outputStream open];
        
    }
    
    //关闭数据流操作
    -(void)close
    {
        [self.outputStream close];
        [self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.outputStream setDelegate:nil];
        [self.inputStream close];
        [self.inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.inputStream setDelegate:nil];
    }
    
    //从client发送数据事件方法
    - (IBAction)sendData:(id)sender {
        flag = 0;   //表示发送
        [self initNetworkCommunication];
        
    }
    
    //从服务端接收数据事件方法
    - (IBAction)receiveData:(id)sender {
        flag = 1;   //表示接收
        [self initNetworkCommunication];
        
    }
    
    -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
        NSString *event;
        switch (streamEvent) {
            case NSStreamEventNone:  //没有事件发生
                event = @"NSStreamEventNone";
                break;
            case NSStreamEventOpenCompleted:  //成功打开流
                event = @"NSStreamEventOpenCompleted";
                break;
            case NSStreamEventHasBytesAvailable:   //这个流有数据能够读,在读取数据时使用
                event = @"NSStreamEventHasBytesAvailable";
                if (flag ==1 && theStream == _inputStream) {
                    NSMutableData *input = [[NSMutableData alloc] init];
                    uint8_t buffer[2048]; //读取数据准备缓冲区,本例中设置的是2048字节,这个大小会对流的读取有非常大影响   
                    int len;
                    while([self.inputStream hasBytesAvailable])
                    {
                        len = [self.inputStream read:buffer maxLength:sizeof(buffer)];  //读取数据到缓冲区
                        if (len > 0)
                        {
                            [input appendBytes:buffer length:len];
                        }
                    }
                    NSString *resultstring = [[NSString alloc] initWithData:input encoding:NSUTF8StringEncoding];
                    NSLog(@"接收:%@",resultstring);
                    self.message.text = resultstring;
                }
                break;
            case NSStreamEventHasSpaceAvailable:   //这个流能够接收数据的写入,在写数据时使用
                event = @"NSStreamEventHasSpaceAvailable";
                if (flag ==0 && theStream == _outputStream) {
                    //输出
                    UInt8 buff[] = "收到啦,服务端。";       //向服务端发送的消息
                    [self.outputStream write:buff maxLength: strlen((const char*)buff)+1];   //向服务端写入数据方法
                     //必须关闭输出流否则,server端一直读取不会停止。
                    [self.outputStream close];
                }
                break;
            case NSStreamEventErrorOccurred:      //数据流错误发生
                event = @"NSStreamEventErrorOccurred";
                [self close];
                break;
            case NSStreamEventEndEncountered:     //数据流结束
                event = @"NSStreamEventEndEncountered";
                NSLog(@"Error:%d:%@",[[theStream streamError] code], [[theStream streamError] localizedDescription]);
                break;
            default:
                [self close];
                event = @"Unknown";
                break;
        }
    
    }
    
    @end
    
                  从代码能够知道。client採用的是 APPLE 自家的 NSStream 来实现的,都是比較简单的基本数据流操作。

         微笑如有哪些不正确的地方,欢迎指出!



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4800455.html
Copyright © 2011-2022 走看看