socket技术常用于即时通讯,断断续续的网络链接,比如断点上传等。目录:
一、环境准备
二、客户端
(一)建立连接
(二)数据收发
三、服务器端
(一)建立连接
(二)接收数据
/************************************************************************************************/
一、环境准备
本文的socket介绍基于git上的第三方库类CocoaAsyncSocket ,目前作者已经更新到 7.4.2版本。git下载地址是:
https://github.com/robbiehanson/CocoaAsyncSocket.git
下载好之后,将RunLoop文件夹下的AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 文件拷贝到我们的项目中来。
添加CFNetwork.framework框架。
在用到socket的文件中引入头文件:
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>
#import "AsyncSocket.h"
#import "AsyncUdpSocket.h"
二、客户端
(一)建立连接
1、首先初始化,并主动连接服务端。
//初始化socket,并设置本controller为代理,
self.socketClient=[[AsyncSocket alloc]initWithDelegate:self]; NSError *error = nil;
//连接服务器,withTimeout:5 ,意思是超过5秒还没有连通的话,就算是连接失败,调用连接失败的代理方法 [self.socketClient connectToHost:self.socketHost onPort:self.socketPort withTimeout:5 error:&error];
并且遵守代理协议
@interface ViewController ()<AsyncSocketDelegate,AsyncUdpSocketDelegate>
2.1、如果上面的socketClient连接成功,就会调用代理方法
/** * 成功连接服务器时调用 */ -(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { NSLog(@"链接成功!"); }
2.2、如果上面的socketClient连接失败,就会调用代理方法
/** * 连接失败,或断开连接时会调用 */ -(void)onSocketDidDisconnect:(AsyncSocket *)sock { NSLog(@"连接失败,连接断开!可以在这里调用重新连接的方法");
//可以将下面这个方法提出来重写一个方法,进行封装,方便调用
//在实际开发中,还要定义标记来判断是服务器掉线,还是用户主动断掉连接的
//[self.socketClient connectToHost:self.socketHost onPort:self.socketPort withTimeout:5 error:&error];
}
(二)数据收发
1、接收数据
如果连接成功,就可以接收数据了,当接收到数据就会调用如下方法:
/** * 当接收数据的时候就会调用 */ -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { // 读取数据,当timeout为负数的时候,不设定超时时限 [self.socketClient readDataToData:data withTimeout:-1 tag:1];
//如果数据分多次接收,那么,可以在这里拼接data数据,并计算已经接收的数据长度,或者对数据进行持续写入操作,保证大文件下载不占用过多内存 }
2、发送数据
当socket连接成功,在上述中的
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port 方法中,准备好data数据,并且调用方法
[self.socketClient writeData:fileData withTimeout:-1 tag:1];
即:
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { NSLog(@"链接成功!"); // 准备要上传的数据,转换为data NSData * fileData=[NSData dataWithContentsOfFile:@"文件路径"]; // 调用socket的发送数据方法 [self.socketClient writeData:fileData withTimeout:5 tag:1]; }
如果数据上传成功,就会调用代理方法:
/** * 发送数据成功时调用 */ -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag { NSLog(@"上传成功!"); }
如果上传或者下载失败,那么就说明连接断了,期间会调用 onSocketDidDisconnect: 方法,在该方法中编写有关的处理代码即可。
三、服务器端
(一)建立连接
为了代码举例方便,假设在服务器端就在app中,那么在viewcontroller中进行代码编写。
- (void)viewDidLoad { [super viewDidLoad]; // 初始化,并设置代理 self.socketServer=[[AsyncSocket alloc]initWithDelegate:self]; // 设置对应的端口号(监听这个端口收到的信息) [self.socketServer acceptOnPort:8080 error:nil]; }
当接收到新的socket
/** * 当接收到新的socket的时候调用 */ -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket { // 获取新收到的socket self.socketNewAcce=newSocket; }
/** * 服务器端连通客户端,就会调用,方法名和客户端的一样 */ -(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { NSLog(@"与客户端连通!"); // 连通后的有关操作,接收数据等 } /** * 与客户端断开连接的时候调用 */ -(void)onSocketDidDisconnect:(AsyncSocket *)sock {
NSLog(@"与客户端断开连接!");
}
(二)接收数据
接收数据只需要在服务器与客户端连通的代理方法中编写即可,
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port。