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 来实现的,都是比較简单的基本数据流操作。

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

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

时间: 2024-11-13 09:29:25

iOS 基于Socket 的 C/S 网络通信结构(下一个)的相关文章

iOS从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题

本文转载至 http://blog.csdn.net/woaifen3344/article/details/41284319 navios 如果有朋友遇到从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题, 下面是我写的一种方案,也就是在loadView这个生命周期函数中调用一个显示导航条,就 可以解决这个问题: [objc] view plaincopyprint? - (void)loadView { [super loadView]; [self.navigationCont

转:iOS中socket详解

一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象: 传输层.会话层.表示层和应用层则被称作主机层,是用户所面向和关心的内容. http协议   对应于应用层 tcp协议    对应于传输层 ip协议     对应于网络层 三者本质上没有可比性.  何况HTTP协议是基于TCP连接的. TCP/IP是传输层协议,主要解决数据如何在网络

iOS的socket开发基础

目录[-] socket简介 tcp和udp的区别 TCP三次握手和四次挥手 TCP三次握手 tcp四次挥手 tcpsocket和udpsocket的具体实现 tcpsocket的具体实现 udpsocket的具体实现 由于博客迁移至www.coderyi.com,文章请看http://www.coderyi.com/archives/429 socket简介 首先让我们通过一张图知道socket在哪里? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口. tcp和ud

基于 Socket 的 UDP 和 TCP 编程介绍

基于 Socket 的 UDP 和 TCP 编程介绍 一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(stream socket)的一种. UDP:用户数据报协议.UDP是一种无连接协议.UDP套接口是数据报套接口(datagram socket)的一种. 二.TCP和UDP介绍 1)基本TCP客户-服务器程序设计基本

基于Socket实现网络编程

Socket是网络上两个程序间双向通讯的一端,它既可以发送请求,也可以接收请求,利用它可以方便的编写网络上数据的传递,在java中,有专门的类类处理用户的请求和响应.利用Socket 类的方法,就可以实现两台计算机之间的通信,那么怎么利用socket进行网络编程呢?我试试水~ 网络中的进程之间是如何进行通信的? 本地进程间通信(IPC)有很多种方法,简而言之可以归结为以下四类: 消息传递(管道,FIFO,消息队列); 同步(互斥量,条件变量,读写锁,文件和写记录锁,信号量): 内存共享(匿名的和

iOS开发— Socket编程

Socket编程 一.了解网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象: 传输层.会话层.表示层和应用层则被称作主机层,是用户所面向和关心的内容. http协议   对应于应用层 tcp协议    对应于传输层 ip协议     对应于网络层  三者本质上没有可比性.  何况HTTP协议是基于TCP连接的. TCP/IP是传输层协议

基于Socket的Android聊天室

1        基于Socket的Android聊天室 Socket通信是网络通信中最常用的技术之一,通过Socket建立的可靠连接,可以让多个终端与服务器保持通信,最典型的应用是建立一个多人聊天程序.本实例使用ServerSocket建立聊天服务器.将服务器端所有的通讯线程保存到一个集合当中,当有用户发来数据,则转发给所有用户,实现聊天室效果.Android端通过使用Socket建立客户端链接,并且在AsyncTask中执行网络读写的任务,将用户输入的内容发送到服务器,并接收服务器发来的数据

细说linux IPC(一):基于socket的进程间通信(上)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 在一个较大的工程当中,一般都会有多个进程构成,各个功能是一个独立的进程在运行.既然多个进程构成一个工程,那么多个进程之间肯定会存在一些信息交换或共享数据,这就涉及到进程间通信.进程间通道有很多种,比如有最熟悉网络编程中的socket.还有共享内存.消息队列.信号.管道等很多方式,每一种方式都有自己的适用情况,在本系列文章中笔者将会对多种进程间通

iOS的socket开发

socket简介 首先让我们通过一张图知道socket在哪里? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口. tcp和udp的区别 在这里就必须讲一下udp和tcp的区别了 TCP:面向连接.传输可靠(保证数据正确性,保证数据顺序).用于传输大量数据(流模式).速度慢,建立连接需要开销较多(时间,系统资源). UDP:面向非连接.传输不可靠.用于传输少量数据(数据包模式).速度快. 关于TCP是一种流模式的协议,UDP是一种数据报模式的协议,这里要说明一下,TCP