美文网首页ios 知识点iOS开发笔记iOS开发大全
学习使用AsyncSocket 进行iOS socket编程

学习使用AsyncSocket 进行iOS socket编程

作者: 逗比小骷髅 | 来源:发表于2016-10-20 18:44 被阅读5116次

       最近工作中使用别人的SDK时看到了AsyncSocket这个类 简单查看了这个类的用处,发现是iOS socket套接字的封装 用于iOS的socket编程,上学时曾学到Linux的socket编程都是C函数,上学时不用功(惭愧),对socket算是听说过,于是有些兴趣再学习学习。

我使用socket编程 用到的通信协议有TCP和UDP。 TCP是可传输控制协议,它的传输是可靠的,需要三次握手建立连接, 四次握手释放链接(具体怎么过程就不多说了),UDP是用户数据报协议 传输是不可靠地。

下载AsyncSockethttps://github.com/robbiehanson/CocoaAsyncSocket类库,将RunLoop文件夹下的AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 文件拷贝到自己的project中

添加CFNetwork.framework, 在使用socket的文件头

一、UDP:

AsyncUdpSocket类是支持UDP协议的socket编程类,使用也很容易,通信的收发过程都有代理可以调用。

self.udpSocket =[[AsyncUdpSocket alloc]initWithDelegate:self];//初始化socket,设置代理为self

self.portTF.text = @"8888";

NSError *error;

[self.udpSocket enableBroadcast:YES error:&error];//设置允许socket广播,如果不设置,则不能发消息

BOOL isBind = [self.udpSocket bindToPort:[self.portTF.text intValue] error:&error];//绑定一个未用的端口,我设置的是8888  初始化一个socket只能绑定一次,多次绑定直接崩 重新绑定得先调用[self.udpSocket close];然后重新生成一个socket再绑定。

接收数据:

[self.udpSocket receiveWithTimeout:-1 tag:0];//接收数据的方法,调用一次就只接受一次发送的数据包,设置timeout为-1就是永不超时 只要向该socket发送数据就能接收到,接收到数据后会调用- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port 这个代理方法,所接受的数据也在该代理方法的data参数里, 上面接受方法里设置的tag值是几,这代理方法的接收到tag值就是几。host就是发消息的那个socket的主机地址。port是上面绑定的端口号(即8888,也是发送消息的socket的端口号)。

这里如果设置的timeout不是-1,当时间到后超时会调用代理-(void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error

发送数据:

NSString *str = self.sendTFV.text;

NSData *data=[str dataUsingEncoding:NSUTF8StringEncoding];

[self.udpSocket sendData:data toHost:self.serverHost port:[self.portTF.text intValue] withTimeout:5 tag:0];//这是发送的方法  发送完后会调用代理-(void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag 这里的tag值与发送时设置的tag一致

这里自己测试时写了自己的小程序玩玩socket udp通信程序 链接: https://pan.baidu.com/s/1o7GGHEM 密码: h4di

demo里有一个server程序、一个client程序。一个server程序可以用来广播搜索同一网段内的client设备,玩的时候可以找三台设备(我用的是一个iPad,两个iPod,iPad装server程序,两个iPod装client程序,iPad广播搜索后会将两个iPod的IP显示出来,在iPad上选择一/两个IP 发送数据,相应的一/两个iPod会收到数据)。

二、TCP

实现tcp协议需要一个服务器一个客户端,他们之间发送消息时需要先建立一个连接,然后才能收发数据。使用的类AsyncScoket。

服务器端:

self.tcpScoket = [[AsyncSocket alloc]initWithDelegate:self];//初始化 设置代理

NSError *error;

[self.tcpScoket acceptOnPort:8888 error:&error];//这个方法是监听8888端口号,接收通过8888端口号发来的连接请求。收到连接后会走代理- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket 在这个代理方法里 需要使用一个数组保存连接的socket,保证此链接是长连接,如果不保存,则连接完后就会自动断开,从而导致无法互相发收消息;例如(我的demo里):在该方法中使用[self.clientSocketMuArr addObject:newSocket];保存此socket。使用[newSocket readDataWithTimeout:-1 tag:0];接收接下来客户端可能发送的消息。

接下来会走代理方法:-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port 该方法中host就是连接的客户端的IP

发送数据:

NSData *data = [self.responseTF.text dataUsingEncoding:NSUTF8StringEncoding];

[self.tcpScoket writeData:data withTimeout:-1 tag:0];这个是发送数据的方法,与udp的发送方法名是不同的,但其功能与UDP的类似,一次只发一个数据。timeout设为-1也是永不超时 调用完之后也有代理方法触发-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

接收数据:

[sock readDataWithTimeout:-1 tag:0];方法名与UDP不同功能上也是类似的 一次只接受一个数据,不调用就不会收到消息,调用之后触发代理- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

客户端:

同样的self.tcpScoket = [[AsyncSocket alloc]initWithDelegate:self];//初始化 设置代理

NSError *error;

BOOL isConnect = [self.tcpScoket connectToHost:@“192.168.3.105” onPort:8888 withTimeout:-1 error:&error];连接服务器,这里的host是服务器的IP,就是你作为服务器的那台设备的IP地址(可以在设置连接WiFi的那里看到),端口号8888就是服务器监听的端口号,注意这里返回的bool值isConnect只是说是否能调用此方法,具体是否连接上服务器要看是否调用代理-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port连接成功后就可以使用[self.tcpScoket writeData:data withTimeout:-1 tag:0];方法向服务器发数据了,收发消息的方法与上面服务器的相同,所触发的代理一是一样的。

这里自己写了小程序socket tcp通信程序 链接: https://pan.baidu.com/s/1bI1gy6 密码: 8tjv demo里有一个server,一个client.

至此是我研究的AsyncSocket,里面还有其他的方法,具体的用法需要的自己去研究吧!

相关文章

网友评论

  • Zero_Jin:可以跟服务器连接成功,并且收到服务发送给我的数据;但是我发送给服务器的数据,服务器就是收不到
  • 卓敦:使用AsyncSocket发信息,但是后台给我一条URL,IP和端口号,还要求我接收数据时要传入用户登录返回的那个sessionid,要怎么传,我看你的demo没有这种操作,新手求教
    卓敦:@CoderQY 楼主的服务器端是用本地电脑作为服务端的,真正开发不是用本地的
    CoderQY:@CoderQY 楼主的 客户端代码 和 服务端代码 都运行在手机上什么意思 ? 原理没明白
    CoderQY:楼主的代码 为什么又 客户端 和服务端 两部分啊? 长连接 不应该是 手机(客户端) 和 后台(服务端) 建立的连接吗? 我是新手 想跟您交流一下
  • jade_xiaohui:请问多个client链接一个server怎么处理 用tcp试了一下只能连接一个client 再连接第二个就erorr 61的错误
  • 花果山松鼠:哥们,你的udp那个demo,密码错误呢,h4di输入后显示密码错误。你再看看还是重新弄一下啊。感谢
  • a72629bf1140:接收数据怎么调用啊
  • alelaile:兄弟 并没有你说的AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 这四个文件啊
    简单周:是不是因为新版的CocoaAsyncSocket中,文件名已经变成GCDAsyncSocket,GCDAsyncUdpSocket了
  • 31377d398f35:您好! 我iPhone(客户端)与iPhone,iPad, iMac 发UDP都可以正常使用,为什么iPhone(客户端)和我们公司自己的WIFi产品和windows PC端他们收不到我发送的UDP呢?请指教...
    左耳进:@我来也风行 我也遇到过,情况是插着数据线就收不到,拔下数据线就正常了,怀疑是连上数据线IP有问题
    31377d398f35:我是在同一个局域网下 端口号也一直, 我之前用OC的不行, 用纯C就OK了!
    逗比小骷髅:@我来也风行 需要在同一个局域网下 端口号也要一致
  • zinder:第一个密码确实有问题
  • 那年那月那花儿:楼主udp密码有问题, 发个正确的, 希望学习学习.
  • zkhCreator:第一个网盘密码有误
  • 8fc99f582558:在大神,你碰到过丢包的问题 用TCP ,接收数据不完全
    加双芋:我也是这个情况,一次包太大,服务器端默认会分包发送,前端再接收到的就是顺序不定的被自动拆分的几个包了,你有什么进展或者疑问,可以沟通沟通
  • StartBoy:楼主你的百度网盘密码错误啊。还希望看下代码啊。
    34bb2a6201da:@逗比小骷髅 第一个密码错误啊
    b058ef79b2e0:楼主,你的第一个链接的密码有误,第二个的OK
    逗比小骷髅:@newyears 没有错啊 在试试吧
  • 强力黑手:你的盘百度进不去呢。

本文标题:学习使用AsyncSocket 进行iOS socket编程

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