【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之一:WiFi UDP和TCP
来源:互联网 发布:伊宁新站怎么做优化 编辑:程序博客网 时间:2024/05/04 14:01
在上一篇文章中,我们通过编写EV3 Port Viewer项目实现了iOS监测EV3的实时端口数据。程序最核心的部分就是我们的开源代码库iOS_WiFi_EV3_Library。那么,在本文中,我们将详细介绍我们这个库的编写。为了完成这个库,本人参考了网上很多资料,主要包括EV3的源代码,win版本的代码库以及Monobrick相关以及网上的各种资料,在此就不一一列举了。由于水平有限,本代码库还存在各种问题,望使用的读者见谅。大家也可以在这个基础之上自己进行改造完善。
为了详细说明代码库的实现,这里我们从需求分析,设计到实现介绍整个库从无到有的过程。
==需求分析:代码库要实现的功能==
从我们的第一篇文章中,我们已经对iOS和EV3的结合方式做了详细的介绍。从中,我们可以总结出,我们要编写的代码库需要实现以下功能:
1)拥有一个连接界面来搜索并连接WiFi局域网内的EV3设备。
2)实时接收EV3的端口数据并且能非常方便地对数据进行处理。
3)能够发送直接命令(Direct Command)到EV3实现对EV3的实时控制。(EV3的源代码中内置两种命令格式:命令Command和直接命令Direct Comand,使用直接命令则EV3可以直接响应,无需在EV3上进行任何的编程,大家可以参考我之前写的Hacking EV3系列文章,那些文章主要讲通过使用开源库btstack来实现用蓝牙来连接EV3,由于要使用btstack需要对iOS设备进行越狱,因此最后选择弃用而使用WiFi,这也是本项目的重要工作之一)
简单一点说就是要实现EV3的wifi连接,发送和接收功能。只要实现了这三个核心功能,那么我们就可以用iOS来控制EV3。
==WiFi连接的方法==
如果是iOS设备之间的无线数据通信,我们可以直接使用iOS的高级框架MultiConnectivity.Framework来实现。但是现在我们要通过iOS来连接一个非iOS设备,我们就只能使用iOS底层的API了。根本就方式就是使用UDP和TCP来进行数据通信。这部分功能对应的API为CFNetwork,这是一个比较底层的C代码的框架。
我们可以选择直接使用CFNetwork来编写,但这势必会非常复杂和困难。还好,我们还有另外一种选择,那就是使用网上的开源库CocoaAsyncSocket。这个开源库使用iOS的GCD在Objective C的层次重新封装了UDP和TCP传输的功能,使得编写UDP和TCP传输的应用变得非常方便。因此,我们就采用了CocoaAsyncSocket来实现UDP和TCP的传输。
==CocoaAsyncSocket的使用==
大家可以从网上下载这个开源库:https://github.com/robbiehanson/CocoaAsyncSocket
我们只需要使用库中的四个文件:
GCDAsyncSocket.h // 实现TCP传输
GCDAsyncSocket.m
GCDAsyncUdpSocket.h // 实现UDP传输
GCDAsyncUdpSocket.m
1.UDP的使用
Step 1:创建实例instance
UDP的使用通过GCDAsyncUdpSocket这个类来实现。因此要使用UDP,我们首先得创建一个GCDAsyncUdpSocket类的实例。比如这里我们创建一个实例命名为udpSocket:
dispatch_queue_t udpSocketQueue = dispatch_queue_create("com.manmanlai.updSocketQueue", DISPATCH_QUEUE_CONCURRENT);
self.udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:udpSocketQueue];
说明一下这个类包含delegate方法(依靠delegate方法来接收处理数据)以及需要定义一个特定的并行Queue来使用。
Step 2:连接UDP到特定端口
这里我们使用这个类中的方法:
1)连接API:bindToPort:error:
2)接收数据API:beginReceiving:
3)关闭API:close
因此,根据这个API我们可以编写一个Method来开始UDP和停止UDP
- (void)startUdpSocket
{
NSError *error = nil;
if (![self.udpSocket bindToPort:UDP_PORT error:&error])
{
NSLog(@"Error starting server (bind): %@", error);
return;
}
if (![self.udpSocket beginReceiving:&error])
{
[self.udpSocket close];
NSLog(@"Error starting server (recv): %@", error);
return;
}
NSLog(@"Udp Echo server started on port %hu", [self.udpSocket localPort]);
}
- (void)stopUdpSocket
{
[self.udpSocket close];
}
Step 3:接收UDP数据
通过delegate方法
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(id)filterContext
接收数据
具体数据如何处理之后再谈。
Step 4:发送UDP数据
- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag
以上是UDP的使用,接下来介绍TCP的使用
2、TCP的使用
Step 1:创建实例instance
和UDP的创建方式一样,只不过改成GCDAsyncSocket类。
dispatch_queue_t tcpSocketQueue = dispatch_queue_create("com.manmanlai.tcpSocketQueue", DISPATCH_QUEUE_CONCURRENT);
GCDAsyncSocket *tcpSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:tcpSocketQueue];
Step 2:连接TCP
连接TCP的API如下:
-(BOOL)connectToHost:(NSString*)host onPort:(uint16_t)port error:(NSError **)errPtr
在使用中,如下所示:
NSError *error = nil;
if (![tcpSocket connectToHost:device.address
onPort:5555
error:&error])
{
NSLog(@"Error connecting: %@", error);
} else {
NSLog(@“Connected");
}
Step 3:发送TCP数据
-(void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
Step 4:接收数据
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag
Step 5:数据处理
通过Delegate方法实现,包含以下几个:
// TCP socket已连接
(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
// TCP socket已断开
(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
// TCP socket已写入数据
(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
// TCP socket已发送数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
以上便是UDP和TCP的使用方法,可以看到是非常的简单明了的。
下一篇文章中,我们将介绍如何使用CocoaAsyncSocket来具体连接我们的EV3机器人,敬请期待!
【本文为原创文章,版权所有,转载请注明出处,谢谢!songrotek@qq.com】
2 0
- 【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之一:WiFi UDP和TCP
- 【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之一:WiFi UDP和TCP
- 【iOS与EV3混合机器人编程系列之五】iOS_WiFi_EV3_Library 剖析之连接EV3
- 【iOS与EV3混合机器人编程系列之六】iOS_WiFi_EV3_Library 剖析之发送命令给EV3
- 【iOS与EV3混合机器人编程系列之一】iOS要干嘛?EV3可以更酷!
- 【iOS与EV3混合机器人编程系列之7】通过蓝牙控制EV3
- 【iOS与EV3混合机器人编程系列之三】编写EV3 Port Viewer 应用监测EV3端口数据
- 【iOS与EV3混合机器人编程系列之二】工欲善其事,必先利其器(准备篇)
- Hacking EV3系列之一:自编iOS app控制EV3之资料收集与分析
- Hacking EV3系列之四:BTstack与iOS通信
- Hacking EV3系列之七:iPhone 手势无线控制LEGO EV3 Gyro Boy 机器人
- c#与matlab混合编程系列之一
- Hacking EV3系列之五:iOS通过BTstack发送message给EV3
- Hacking EV3系列之六:iOS使用Direct Command 控制EV3
- 剖析网络编程-TCP&UDP
- linux socket编程之TCP与UDP
- linux socket编程之TCP与UDP
- java网络编程之UDP与TCP
- 轻量级web server Tornado代码分析
- 黑马程序员_java基础篇之API
- linux-awk-grep-sed
- Linux已经完全统治了这个世界:反对开源社区愚不可及
- n个人围成一圈报数,从1报到3,报到3的人退出,然后依次循环,直到剩下最后一人,这人是第几个人?
- 【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之一:WiFi UDP和TCP
- hive分区(partition)简介
- No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional
- 精通安卓性能优化-第五章(一)
- 维基1169传纸条
- 编程算法 - 求1+2+...+n(模板类) 代码(C++)
- 【转载自mos中文文章】Oracle 集群 10gR2/ 11gR1/ 11gR2/ 12cR1 诊断信息收集指南
- C#测试代码段性能耗时
- 详解Android应用如何匹配不同的手机分辨率