这篇文章,我们介绍CocoaAsyncSocket框架的使用,主要介绍实现客户端/服务器端代码,相信在网上已经很多这样的文章了,这里做一下自己的总结。这里介绍使用GCD方式

一.客户端

1.下载地址

读者可以在github下载框架源码 https://github.com/robbiehanson/CocoaAsyncSocket

下载后,可以看到在Examples下面可以看到很多例子,如果读者自学能力高,可以略过下面的文章。

2.开始使用

1)在 \Source\GCD 目录下,我们可以看到GCDAsyncSocket的h与m文件,我们复制这两个文件到项目中。

2)我们在代码里面导入头文件 #import "GCDAsyncSocket.h" 与 协议 GCDAsyncSocketDelegate。

3.代码

1)定义全局变量 GCDAsyncSocket *_socket;

2)开始连接服务器

- (void) connect2Server() {
//1.主机与端口号
NSString *host = @"127.0.0.1";
int port = ; //初始化socket,这里有两种方式。分别为是主/子线程中运行socket。根据项目不同而定
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];//这种是在主线程中运行
//_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; 这种是在子线程中运行 //开始连接
NSError *error = nil;
[_socket connectToHost:host onPort port error:&error];
if(error) {
NSLog("error:%@", error);
} }

3)登录

-(void)login() {
//登录String
NSString *loginStr = "iam:I am login!";
NSData *loginData = [loginStr dataUsingEncoding: NSUTF8StringEncoding];
//发送登录指令。-1表示不超时。tag200表示这个指令的标识,很大用处
[_socket writeData: loginData withTimeout:- tag:];
}

4)开始聊天

//发送聊天数据
-(void) sendMsg: (NSString*)msg{
NSString *sendMsg = [@"msg:I send message to u!"];
NSData *sendData = [sendMsg dataUsingEncoding: NSUTF8StringEncoding];
[_socket writeData; sendData withTimeout:- tag:];
}

5)实现协议delegate

#pragma mark -socket的代理

#pragma mark 连接成功

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
//连接成功
NSLog(@"%s",__func__);
} #pragma mark 断开连接
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
if (err) {
NSLog(@"连接失败");
}else{
NSLog(@"正常断开");
}
} #pragma mark 数据发送成功
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(@"%s",__func__);
//发送完数据手动读取
[sock readDataWithTimeout:- tag:tag];
} #pragma mark 读取数据
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//代理是在主/子线程调用
NSLog(@"%@",[NSThread currentThread]);
NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if (tag == ) {
//登录指令
}else if(tag == ){
//聊天数据
}
NSLog(@"%s %@",__func__,receiverStr);
}

二.服务器端

服务器端不可能在iphone/ipad上运行,所以我们新建一个单纯命令行的项目。

1.新建一个类MyChatServer,并且开放公共方法startServer,头文件如下

#import <Foundation/Foundation.h>

@interface MyChatServer : NSObject
/**
* 开启聊天服务器
*/
-(void)startServer;
@end

2.在main文件中,开启聊天服务器,并且开启主运行循环,让服务器接收到客户端请求

//实现聊天
MyChatServer *chatServer = [[MyChatServer alloc] init];
[chatServer startServer];
//开启主运行循环
[[NSRunLoop currentRunLoop] run];

3.在MychatServer.m文件中,我们开始实现GCDAsyncSocket的方法(下面代码都在MychatServer.m中)

1)首先建一个成员变量array对象,把所有的socket(客户端)对象保存在里面

@property(strong,nonatomic)NSMutableArray *clientSocket;

私有变量serverSocket与golbal_queue

GCDAsyncSocket *_serverSocket;
dispatch_queue_t _golbalQueue;

2)在类初始化的时候,我们初始化私有变量与成员变量

-(instancetype)init{
if (self = [super init]) {
_clientSocket = [NSMutableArray array];
//创建全局queue
_golbalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//创建服务端的socket,注意这里的是初始化的同时已经指定了delegate
_serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_golbalQueue];
}
return self;
}

3)开启服务器聊天startServer

-(void)startChatServer{
//打开监听端口
    NSError *err;
[_serverSocket acceptOnPort:12345 error:&err];
if (!err) {
NSLog(@"服务开启成功");
}else{
NSLog(@"服务开启失败");
}
}

4)实现delegate

#pragma mark 有客户端建立连接的时候调用
-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
//sock为服务端的socket,服务端的socket只负责客户端的连接,不负责数据的读取。 newSocket为客户端的socket
    NSLog(@"服务端的socket %p 客户端的socket %p",sock,newSocket);
//保存客户端的socket,如果不保存,服务器会自动断开与客户端的连接(客户端那边会报断开连接的log)
NSLog(@"%s",__func__);
[self.clientSocket addObject:newSocket]; //newSocket为客户端的Socket。这里读取数据
[newSocket readDataWithTimeout:- tag:];
} #pragma mark 服务器写数据给客户端
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(@"%s",__func__);
[sock readDataWithTimeout:- tag:];
} #pragma mark 接收客户端传递过来的数据
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//sock为客户端的socket
NSLog(@"客户端的socket %p",sock);
//接收到数据
NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"length:%ld",receiverStr.length);
// 把回车和换行字符去掉,接收到的字符串有时候包括这2个,导致判断quit指令的时候判断不相等
receiverStr = [receiverStr stringByReplacingOccurrencesOfString:@"\r" withString:@""];
receiverStr = [receiverStr stringByReplacingOccurrencesOfString:@"\n" withString:@""]; //判断是登录指令还是发送聊天数据的指令。这些指令都是自定义的
//登录指令
if([receiverStr hasPrefix:@"iam:"]){
// 获取用户名
NSString *user = [receiverStr componentsSeparatedByString:@":"][];
// 响应给客户端的数据
NSString *respStr = [user stringByAppendingString:@"has joined"];
[sock writeData:[respStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:- tag:];
}
//聊天指令
if ([receiverStr hasPrefix:@"msg:"]) {
//截取聊天消息
NSString *msg = [receiverStr componentsSeparatedByString:@":"][];
[sock writeData:[msg dataUsingEncoding:NSUTF8StringEncoding] withTimeout:- tag:];
}
//quit指令
if ([receiverStr isEqualToString:@"quit"]) {
//断开连接
[sock disconnect];
//移除socket
[self.clientSocket removeObject:sock];
}
NSLog(@"%s",__func__);
}

查看本文章之前,可以看看

IOS Socket 03-建立连接与登录

可以关注本人的公众号,多年经验的原创文章共享给大家。

IOS Socket 04-利用框架CocoaAsyncSocket实现客户端/服务器端的更多相关文章

  1. iOS:基于Socket的第三方框架CocoaAsyncSocket的使用

    CocoaAsyncSocket无疑是目前封装得最完善的Socket库了:支持异步TCP/UDP,支持GCD,Objective-C接口封装,同时还有日志跟踪功能,使用此日志跟踪,程序员可以很方便的进 ...

  2. IOS Socket 05-XMPP开始&安装服务器openfire&安装配置客户端

    1. 即时通讯技术简介(IM) 即时通讯技术(IM-Instant Messageing)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方 ...

  3. IOS Socket 03-建立连接与登录

    1. 搭建python服务器 这里我们用到python服务器Socket Server.如何运行Server?下面介绍 1)通过百度云下载文件 http://pan.baidu.com/s/1i5yb ...

  4. iOS Socket 整理以及CocoaAsyncSocket、SRWebSocket源码解析(一)

    写在准备动手的时候: Socket通讯在iOS中也是很常见,自己最近也一直在学习Telegram这个开源项目,Telegram就是在Socket的基础上做的即时通讯,这个相信了解这个开源项目的也都知道 ...

  5. iOS socket Stream 服务器端 及 客户端 演示

    iOS socket Stream 测试环境,mac osx 10.8 一:建立服务器端 由于mac osx10.8 已经集成 python2和 Twisted,我们可以直接利用此,构建一个简单的so ...

  6. iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇

    完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...

  7. 【转】iOS超全开源框架、项目和学习资料汇总

    iOS超全开源框架.项目和学习资料汇总(1)UI篇iOS超全开源框架.项目和学习资料汇总(2)动画篇iOS超全开源框架.项目和学习资料汇总(3)网络和Model篇iOS超全开源框架.项目和学习资料汇总 ...

  8. iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇

    iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...

  9. .NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序

    .NET 跨平台RPC框架DotNettyRPC   DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...

随机推荐

  1. 开发前准备 va2015安装

    1.下载vs2015 2.进行安装(同时安装node.js.npm与Android SDK,会省很多时间) 安装的时候要选择自定义安装 如果先安装了Android SDK的话就不要勾选了,我就是勾选了 ...

  2. Unity随记

    //切换场景时怎么能让音乐不停? /////////////////////////////////////////////////////////////////// //切换场景时怎么防止某个物体 ...

  3. Tomcat的优化

    Tomcat的优化配置 修改tomcat的config目录下server.xml文件 <Connector port="9021"  protocol="HTTP/ ...

  4. jsp页面输入小写金额转大写

    <script> function chineseNumber(num){ if (isNaN(num) || num > Math.pow(10, 12)) return &quo ...

  5. ANSI C 所有的转义字符

    \a 响铃符 \b 回退符 \f 换页符 \n 换行符 \r 回车符 \t 横向制表符 \v 纵向制表符 \\ 反斜杠 \? 问号 \' 单引号 \" 双引号 \000 八进制数 \xhh ...

  6. Clover 资源管理器 http://cn.ejie.me/

    附件列表 clover.jpg

  7. VMware Workstation虚拟机中的Linux通过NAT模式共享上网配置教程

    VMware Workstation虚拟机中的Linux通过NAT模式共享上网配置教程 在VMware Workstation虚拟机下面,Linux虚机要上网,一般是桥接模式,但我自己的电脑上网的环境 ...

  8. mysql入门安装遇到问题_2016-10-28

    1. brew安装完mysql之后直接输入mysql -u root -p 显示 can't connect to mysql server through socket, 后来问题应该是server ...

  9. 一个好用的C#类型转换器

    public static object ChangeType(object value, Type targetType) { if (targetType.IsGenericType && ...

  10. Usart的单线半双工模式(stm32F10x系列)

    这两天折腾CTS/RTS硬件流控,看到说232协议的CTS/RTS只是用来做半双工换向使用的.正好手头上有块stm32的板子,看了看stm32的Usart,竟然发现支持的是单线半双工.232里面毕竟4 ...