IOS Socket 04-利用框架CocoaAsyncSocket实现客户端/服务器端
这篇文章,我们介绍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 04-利用框架CocoaAsyncSocket实现客户端/服务器端的更多相关文章
- iOS:基于Socket的第三方框架CocoaAsyncSocket的使用
CocoaAsyncSocket无疑是目前封装得最完善的Socket库了:支持异步TCP/UDP,支持GCD,Objective-C接口封装,同时还有日志跟踪功能,使用此日志跟踪,程序员可以很方便的进 ...
- IOS Socket 05-XMPP开始&安装服务器openfire&安装配置客户端
1. 即时通讯技术简介(IM) 即时通讯技术(IM-Instant Messageing)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方 ...
- IOS Socket 03-建立连接与登录
1. 搭建python服务器 这里我们用到python服务器Socket Server.如何运行Server?下面介绍 1)通过百度云下载文件 http://pan.baidu.com/s/1i5yb ...
- iOS Socket 整理以及CocoaAsyncSocket、SRWebSocket源码解析(一)
写在准备动手的时候: Socket通讯在iOS中也是很常见,自己最近也一直在学习Telegram这个开源项目,Telegram就是在Socket的基础上做的即时通讯,这个相信了解这个开源项目的也都知道 ...
- iOS socket Stream 服务器端 及 客户端 演示
iOS socket Stream 测试环境,mac osx 10.8 一:建立服务器端 由于mac osx10.8 已经集成 python2和 Twisted,我们可以直接利用此,构建一个简单的so ...
- iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇
完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...
- 【转】iOS超全开源框架、项目和学习资料汇总
iOS超全开源框架.项目和学习资料汇总(1)UI篇iOS超全开源框架.项目和学习资料汇总(2)动画篇iOS超全开源框架.项目和学习资料汇总(3)网络和Model篇iOS超全开源框架.项目和学习资料汇总 ...
- iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇
iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...
- .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 ...
随机推荐
- ServletContext获取的方法
ServletContext 代表当前web应用 如何获取ServletContext对象 ServletConfig对象中维护了ServletContext对象的引用,可以通过以下方式获得 Ser ...
- Guidelines for accessing OneDrive from an app
Guidelines for accessing OneDrive from an app https://msdn.microsoft.com/en-us/library/windows/apps/ ...
- OS 系统下安装MySql 配置MySql环境变量
学习Hive需要,闲话不说 本文的内容: 下载Mysql for Mac 下载Mysql Workbench 安装 Mysql 和 Mysql Workbench 配置Mysql在OS 系统上的环境变 ...
- vs2015 无法启动IIS Express Web服务器
今天在VS2015上装了 之后无法启动IIS Express Web服务器. 然后我去查看了windows日志发现vs创建的虚拟目录不见了(至于是不是以上原因导致的没去查明) 然后在vs2015中点击 ...
- 为什么LTE系统的最小时间单位是Ts?
之前一直在做LTE物理层相关的工作,一直有个疑惑, 在36.211开头的一章定义Ts的大小是1/(15000*2048)s,为什么定义这么一个奇怪的unit time. 最近才反应过来,这跟FFT/I ...
- C#实现按键精灵的'找图' '找色' '找字'的功能
背景:游戏辅助功能通常使用按键精灵编写脚本,按键精灵的最大卖点就是能够找到画面中字,图,色,这对于模拟用户鼠标操作至关重要,这能找到道具,找到血量,实现自动打怪,自动补血,自动买卖道具,博主闲来无聊, ...
- Redis多机常用架构-主从
本文内容摘录自同事Perry Zhang的讲解,如需转载须本人同意. 1.主从 命令:slaveof <IP><PORT> redis主从配置:redis支持master-sl ...
- java 线程安全不线程不安全
经常看到一些类,有的说线程安全,有的说线程不安全,顿时懵逼. 线程安全不安全,主要是在多线程执行的情况下,如果由于线程之间抢占资源而造成程序的bug即为线程不安全,下面就拿arraylist 和Vec ...
- 自己封装的一个无限滚动 mark 待传
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- 河南省第五届ACM程序设计大赛
D: 遥 控 器 #include<cstdio> #include<cstring> #include<iostream> #include<algor ...