美文网首页iOS开发历程专注iOS开发iOS开发之借鉴
iOS使用CocoaAsyncSocket框架socket通信的

iOS使用CocoaAsyncSocket框架socket通信的

作者: EdwardSelf | 来源:发表于2016-06-25 20:35 被阅读7658次

首先得引入CocoaAsyncSocket这个类库,然后建两个工程,分别写服务器端和客户端的,客户端的IP地址要写自己电脑的哦,端口号要相同。

服务器端的demo:

#import"ViewController.h"

#import"GCDAsyncSocket.h"

@interfaceViewController()

@property(weak,nonatomic)IBOutletUITextField*portF;

@property(weak,nonatomic)IBOutletUITextField*messageTF;

@property(weak,nonatomic)IBOutletUITextView*showContentMessageTV;

//服务器socket(开放端口,监听客户端socket的链接)

@property(nonatomic)GCDAsyncSocket*serverSocket;

//保护客户端socket

@property(nonatomic)GCDAsyncSocket*clientSocket;

@end

@implementationViewController

#pragma mark -服务器socket Delegate

- (void)socket:(GCDAsyncSocket*)sock didAcceptNewSocket:(GCDAsyncSocket*)newSocket{

//保存客户端的socket

self.clientSocket= newSocket;

[selfshowMessageWithStr:@"链接成功"];

[selfshowMessageWithStr:[NSStringstringWithFormat:@"服务器地址:%@ -端口:%d", newSocket.connectedHost, newSocket.connectedPort]];

[self.clientSocketreadDataWithTimeout:-1tag:0];

}

//收到消息

- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag{

NSString*text = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

[selfshowMessageWithStr:text];

[self.clientSocketreadDataWithTimeout:-1tag:0];

}

//发送消息

- (IBAction)sendMessage:(id)sender {

NSData*data = [self.messageTF.textdataUsingEncoding:NSUTF8StringEncoding];

//withTimeout -1:无穷大,一直等

//tag:消息标记

[self.clientSocketwriteData:datawithTimeout:-1tag:0];

}

//开始监听

- (IBAction)startReceive:(id)sender {

//2、开放哪一个端口

NSError*error =nil;

BOOLresult = [self.serverSocketacceptOnPort:self.portF.text.integerValueerror:&error];

if(result && error ==nil) {

//开放成功

[selfshowMessageWithStr:@"开放成功"];

}

}

//接受消息,socket是客户端socket,表示从哪一个客户端读取消息

- (IBAction)ReceiveMessage:(id)sender {

[self.clientSocketreadDataWithTimeout:11tag:0];

}

- (void)showMessageWithStr:(NSString*)str{

self.showContentMessageTV.text= [self.showContentMessageTV.textstringByAppendingFormat:@"%@\n",str];

}

- (void)viewDidLoad {

[superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

// 1、初始化服务器socket,在主线程力回调

self.serverSocket= [[GCDAsyncSocketalloc]initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];

}

- (void)didReceiveMemoryWarning {

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

服务器端的storyboard

客户端的demo:

#import"ViewController.h"

#import"GCDAsyncSocket.h"

@interfaceViewController()

@property(weak,nonatomic)IBOutletUITextField*addressTF;

@property(weak,nonatomic)IBOutletUITextField*portTF;

@property(weak,nonatomic)IBOutletUITextField*messageTF;

@property(weak,nonatomic)IBOutletUITextView*showMessageTF;

//客户端socket

@property(nonatomic)GCDAsyncSocket*clinetSocket;

@end

@implementationViewController

#pragma mark - GCDAsynSocket Delegate

- (void)socket:(GCDAsyncSocket*)sock didConnectToHost:(NSString*)host port:(uint16_t)port{

[selfshowMessageWithStr:@"链接成功"];

[selfshowMessageWithStr:[NSStringstringWithFormat:@"服务器IP:%@", host]];

[self.clinetSocketreadDataWithTimeout:-1tag:0];

}

//收到消息

- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag{

NSString*text = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

[selfshowMessageWithStr:text];

[self.clinetSocketreadDataWithTimeout:-1tag:0];

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{

[self.viewendEditing:YES];

}

//开始连接

- (IBAction)connectAction:(id)sender {

//2、连接服务器

[self.clinetSocketconnectToHost:self.addressTF.textonPort:self.portTF.text.integerValuewithTimeout:-1error:nil];

}

//发送消息

- (IBAction)sendMessageAction:(id)sender {

NSData*data = [self.messageTF.textdataUsingEncoding:NSUTF8StringEncoding];

//withTimeout -1 :无穷大

//tag:消息标记

[self.clinetSocketwriteData:datawithTimeout:-1tag:0];

}

//接收消息

- (IBAction)receiveMessageAction:(id)sender {

[self.clinetSocketreadDataWithTimeout:11tag:0];

}

- (void)showMessageWithStr:(NSString*)str{

self.showMessageTF.text= [self.showMessageTF.textstringByAppendingFormat:@"%@\n", str];

}

- (void)viewDidLoad {

[superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

//1、初始化

self.clinetSocket= [[GCDAsyncSocketalloc]initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];

}

- (void)didReceiveMemoryWarning {

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

客户端的storyboard图

写完后,分别运行两个工程,开启服务器,textView里会显示开放成功,然后在客户端里连接,连接成功后,便可以在textfield里打字了,发送后,服务器会收到消息,同理,服务器发送消息,客户端也可以收到。

流程:

1、先运行服务器,点击开始监听,会出现 “开放成功”4个字。

服务端

2、打开客户端,填写自己的IP地址,点击开始连接,这时连接成功会显示“链接成功”4个字

服务端

3、当我输入“111”,并点击发送,可以在服务器的textView里收到信息。当然反向也可。

如果失败的话,可以把模拟器之前运行的给删了,按照流程重新运行一下。

相关文章

网友评论

  • a632073b5a6a:楼主,麻烦问一下这个消息发送失败怎么监听啊。谢谢:joy:
    EdwardSelf:@lyq226809 我记得好像有消息发送失败的回调,即使没有可以跟服务器一起写一个超时操作
  • writeSpace:if we're in the real pre-commit handler we can't actually add any new fences due to CA restriction 报这个是为什么啊?
  • 31377d398f35:您好! 我iPhone(客户端)与iPhone,iPad, iMac 发UDP都可以正常使用,为什么iPhone(客户端)和我们公司自己的WIFi产品和windows PC端他们收不到我发送的UDP呢?请指教...
  • lionnner:楼主,问下你:
    当后台服务发过来的包是断包怎么处理呢,
    比方说 约束好的 head里面告诉了 包的长度,然后收到的长度不够 这时候肯定是不能处理接收到的data的,之后再也没收到后面的包了,需要调用哪个方法吗
    EdwardSelf:@lionnner 服务器循环发,并且你们协议定一种握手方式,握手成功了,再接受并且返回标志,让服务器停止发。或者服务器计算头和所有数据的字节和,客户端接收到也计算头和字节和,当两者相等的时候,再进行解包。我想到这两种方法。
  • frankyfz:你好,请问 服务器地址 和 端口 已经固定怎么连接 我运行客户端之后 输入服务器地址 和 端口号 一直连接不成功
    七堇年华cc:@EdwardSelf 其实就是两个移动设备之间传输文件,我现在的做法是开UDP广播,接受到另一设备正在广播的UDP,获得ip和port,然后对该host发TCP连接,成功后自身开httpserver,目前还在研究,你说的开放端口,不太理解什么意思,请赐教。
    EdwardSelf:@七堇年华cc 你的服务器有没有先开放端口
    七堇年华cc:我也出现跟你同样的问题,客户端输的是服务器端的ip和port,点开始连接,没任何反应,在同一网络下面的,你解决了吗?
  • c1e6ff74ff0b:请问楼主,为什么我用两个手机运行两个客服端,只要一个连接成功另外一个就一定会断开连接呢?这个互踢是怎么产生的?
    EdwardSelf:@牵手笑流年 这个我觉得还是去网上找找别人推荐的排行榜
    c1e6ff74ff0b:@EdwardSelf 恩,果然是这样,多谢指教. 另外想请教一下,我想系统的学一下iOS的网络编程,该按照怎样的流程去学呢?有没有相关的书或者教程推荐一下,谢谢啦!
    EdwardSelf:@牵手笑流年 在- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket代理里,服务器把新连接的客户端保存为当前的客户端,那之前的一个肯定被就丢了,如果你在被踢掉的客户端的didDisconnect代理里打印error,发现错误是GCDAsyncSocketClosedError,也就是服务器主动踢掉了之前的客户端,保存了新连接来的客户端。
  • changeWong:楼主,因为最近在研究这个socket通讯,要使多个设备之间,一个作为主机(即服务器),其他作为副机(即客户端),然后在同一个局域网内可以相互收发信息。但是看了你的Demo,是自己手动输入服务器的ip地址才行,要如何做,才能做到不需要自己输入ip,就能在同一个网络里面?
    EdwardSelf:@changeWong  如果你固定服务器的ip地址,端口号自定义的肯定知道,那么客户端直接连接不就可以了。问题应该在固定服务器的ip地址上。
  • 小蜗牛飞:为什么客户端无法链接成功
  • 30d430c75985:你好,刚好在做一个项目需要Ipad Socket通信和pc端同步,服务器已经搭好了,客户端这边只要接受PC的数据和给PC发送数据,看了你的客户端的demo:代码就可以完成我项目需求吧?服务器这边我已经搭好了,就不需要像你那样在弄个服务端的demo吧?第一接触TCP很多不太清楚,谢谢
    EdwardSelf:@____Hm 正常情况下,你的客户端写好后在一个局域网下,ip地址和端口号相同就可以连接上。
    30d430c75985:@EdwardSelf 就是局域网,同一个ip
    EdwardSelf:@____Hm 保证在同一个网络下,ip地址和端口号要相同
  • 多啦A梦tiao:作者有什么联系方式么 私聊了有些问题想问下。
    EdwardSelf:@多啦A梦tiao 可以发简信给我
  • Z了个L:大牛,这个框架在前台没有问题,在后台会不会有问题哦?如果在后台,需不需要配置一下Xcode环境。 :grin:
    EdwardSelf:@Z了个L 正常情况不会啊,因为你可以在一个模拟器上同时运行两个demo,你先运行服务器端,这样你肯定要切出来运行客户端的。你会发现仍然可以收到消息。
    Z了个L:切换到home时的状态. :grin:
    EdwardSelf:@Z了个L 你说的后台是切换到home时的状态还是服务器后端
  • 我是卖报滴小行家:像QQ这种通讯,手机既是客户端又是服务端么?
    EdwardSelf:@我是卖报滴小行家 这个暂时没研究过,不过去搜索一下,肯定有人研究过这方面。
    我是卖报滴小行家:@EdwardSelf 谢谢你,你研究过怎么在两个不同的ip地址之间进行通信么?
    EdwardSelf:@我是卖报滴小行家 http://wenku.baidu.com/link?url=EROUDN3f-ob1iHNPmDiKwUtwpolgFBAD59Qjh8QWeQplRVxfEzGmf3gGMFarUTyYCuhAEVAFG4GlUaXA_-886OqlkVcD6yV5Yd2j36KOU4m 参考这里,我不清楚QQ如何做的,不好回答
  • c2fffd2b0090:你好 ,为什么我只写客户端的代码,可以连接成功,但是我发送消息,其他人收不到呀
    EdwardSelf:@打了鸡血 不太懂你的意思,你是说你没写服务器的代码?socket是服务器和客户端双向连接,没有服务器自然不能建立连接
  • JopYin:楼主你的demo还能分享给我吗?我有一个疑问,模拟器要同时运行服务器端demo和客户端demo吗?
    EdwardSelf:@JopYin https://github.com/edwardGG 可以去下载,模拟器先运行服务端,再回到桌面运行客户端,文章最后写的流程你再仔细看一下。
    JopYin:@JopYin 我的邮箱605519902@qq.com,谢谢楼主
  • 凯文Kevin21:楼主,你的demo客户端连接上了服务器端的端口和ip, 老是断开连接,是什么原因呢。
    凯文Kevin21:@EdwardSelf 有这种可能。。
    EdwardSelf:@七秒小鱼人 我使用的时候好像从没这种情况啊,其他人好像也没有这个情况。有没有可能你的网络不太稳定
  • 咋了爸爸:我的qq 920101141 方便加一下qq 交流一下吗
    DSperson:@咋了爸爸 看你的头像...
    果然是猿粪
    咋了爸爸:@DSperson 缘分呐 哈哈哈
    DSperson:随便一番 就把你抓到了
  • 咋了爸爸:你好 这个有demo吗 给我一份ok吗
    EdwardSelf:@咋了爸爸 https://github.com/edwardGG demo在上面,两个都在

本文标题:iOS使用CocoaAsyncSocket框架socket通信的

本文链接:https://www.haomeiwen.com/subject/iseadttx.html