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 来实现的,都是比較简单的基本数据流操作。
如有哪些不正确的地方,欢迎指出!
版权声明:本文博主原创文章,博客,未经同意不得转载。
iOS 基于Socket 的 C/S 网络通信结构(下一个)的更多相关文章
- iOS从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题
本文转载至 http://blog.csdn.net/woaifen3344/article/details/41284319 navios 如果有朋友遇到从当前隐藏导航界面push到下一个显示导航界 ...
- C#基于Socket的简单聊天室实践
序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...
- iOS开发— Socket编程
Socket编程 一.了解网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被 ...
- 基于 socket.io, 简单实现多平台类似你猜我画 socket 数据传输
一.前言 socket.io 实现了实时双向的基于事件的通讯机制,是基于 webSocket 的封装,但它不仅仅包括 webSocket,还对轮询(Polling)机制以及其它的实时通信方式封装成了通 ...
- 基于socket构造c/s 架构软件
1.socket作用 socket层介于应用层和传输层之间,它起着连接应用层和传输层的功能,同时它能连接应用层和网络层. socket把复杂的tcp/ip协议隐藏在socket接口后面,对用户来说,一 ...
- 基于Socket网络编程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a2011480169/article/details/73602708 博客核心内容: 1.Sock ...
- iOS的socket开发基础
目录[-] socket简介 tcp和udp的区别 TCP三次握手和四次挥手 TCP三次握手 tcp四次挥手 tcpsocket和udpsocket的具体实现 tcpsocket的具体实现 udpso ...
- 细说linux IPC(一):基于socket的进程间通信(上)
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 在一个较大的project其中 ...
- tcp连接是基于socket通信的吗
https://zhidao.baidu.com/question/1305788160020716299.html ------ 网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字 ...
随机推荐
- Android 电源系列小结s
package com.ritterliu.newBatteryWidget; import android.app.Activity; import android.app.Service; imp ...
- 在Linux下使用iconv转换字符串编码
在Linux下写C程序,尤其是网络通信程序时经常遇到编码转换的问题,这里要用到iconv函数库. iconv函数库有以下三个函数 123456 #include <iconv.h>icon ...
- 64位WINDOWS系统环境下应用软件开发的兼容性问题(CPU 注册表 目录)
应用软件开发的64 位WINDOWS 系统环境兼容性 1. 64 位CPU 硬件 目前的64位CPU分为两类:x64和IA64.x64的全称是x86-64,从名字上也可以看出来它和 x86是兼容的,原 ...
- Swagger+Spring MVC框架学习分享
[html] view plain copy 最近参与公司接口编写,Android和IOS端都要调用这些接口,需要对接调试,如果没有一个接口文档,管理接口,别人用了接口,也不知道接口怎么用,接口上有什 ...
- stl 迭代子的失效
迭代子是STL中很重要的特性,但是其很脆弱(我个人认为),因为使用它的条件很苛刻,一不小心就失效了.其在两中情况下可能会失效. 1.当容器有插入操作时 在初始化了迭代子后,如果容器有插入操作时,迭代子 ...
- rsyslog 走tcp通讯配置
发送端: local5.* @@192.168.32.76 front-end:/usr/local/nginx/logs# cat /etc/rsyslog.conf 日志服务器端配置: # Pro ...
- The Highest Mark(01背包)
The Highest Mark Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 飘逸的python - 有的升序有的降序的情况下怎么多条件排序
之前在统计导出各区服玩家消费的时候需要进行升序降序混搭的多条件排序. 需求是这样的.区服从小到大排,如果区服相同,则按消费从大到小排. 实现方法是利用python的sort算法是稳定排序,对数据进行多 ...
- 万圣节福利:红孩儿3D引擎开发课程《3ds max导出插件初步》
ds max文件夹,插件文件夹以及3ds max的可执行程序文件夹: 位的,这里要改成x64,否则启动程序后3ds max会提示"不是有效的win32程序"之类的对话框. 然后要将 ...
- JavaSE复习日记 : 循环语句(for/while/do while)
/* * 循环语句(for循环,while和do while循环) */ /* * for循环语句 * * for循环语法: * for (表达式1;表达式2;表达式3 ){ * java语句 * } ...