美文网首页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 报这个是为什么啊?
      • 我来也风行:您好! 我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,点开始连接,没任何反应,在同一网络下面的,你解决了吗?
      • 牵手笑流年:请问楼主,为什么我用两个手机运行两个客服端,只要一个连接成功另外一个就一定会断开连接呢?这个互踢是怎么产生的?
        EdwardSelf:@牵手笑流年 这个我觉得还是去网上找找别人推荐的排行榜
        牵手笑流年:@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