CocoaAsyncSocket网络通信之web/iOS通信
AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性:队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你。
自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接。
委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用。
基于run loop的,而不是线程的。虽然可以在主线程或者工作线程中使用它,但你不需要这样做。它异步的调用委托方法,使用NSRunLoop。委托方法包括socket的参数,可让你在多个实例中区分。
自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部。
支持基于IPV4和IPV6的TCP流
AsyncUdpSocket是UDP/IP socket网络库,包装自CFSocket。它的工作很像TCP版本,只不过是用于处理UDP的。它包括基于非阻塞队列的发送接收操作,完整的委托支持,基于runloop,自包含的类,以及支持IPV4和IPV6。
这里进入正题了:现在我们要实现一个功能,将电脑里的mp4文件传输到手机上中并进行播放。
功能不是太复杂,我们这里就选用GCDAsyncSocket和WebSocket进行web通信实现文件传输功能。
我们的目的是完成下面一个效果,app启动后显示手机的IP地址和端口号。
图1这样我们就可以打开电脑相应的链接,唤醒项目中的upload.html文件选择.mp4文件
图2点击submit后,app界面就会显示出上传文件的名称及本地路径。
图3点击播放,就可以播放相应的mp4文件。
图4获取手机本地IP地址我们是自定义了一个SYYIpHelper类,实现以下方法,就可以的到IP地址
+ (NSString *)deviceIPAdress {
NSString *address = @"an error occurred when obtaining ip address";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
success = getifaddrs(&interfaces);
if (success == 0) { // 0 表示获取成功
temp_addr = interfaces;
while (temp_addr != NULL) {
if( temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}}}}
freeifaddrs(interfaces);
return address;
}
端口号我们可以根据httpServer类的 listeningPort获取到。
端连接及数据传输我们是通过MyHTTPConnection类来实现的。
在数据上传完成的代理回调方法- (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header中获取的。
MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];
NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent];
拿到文件名和本地路径,通过通知方式传出这两个值,在app界面刷新,即图3效果。
然后我们就可以调用播放器播放文件了。
//1.拿到路径
NSURL *url = [[NSURL alloc]initFileURLWithPath:self.PlayerUrl];
// 2.创建AVPlayerItem
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
// 3.创建AVPlayer
_player = [AVPlayer playerWithPlayerItem:item];
// 4.添加AVPlayerLayer
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
layer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
[self.view.layer addSublayer:layer];
[_player play];
相关代码可到github下载:下载地址