【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之中的一个:WiFi UDP和TCP

在上一篇文章中。我们通过编写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机器人,敬请期待!

【本文为原创文章。版权全部,转载请注明出处。谢谢![email protected]】

时间: 2024-12-22 15:19:33

【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之中的一个:WiFi UDP和TCP的相关文章

【iOS与EV3混合机器人编程系列之四】iOS_WiFi_EV3_Library 剖析之一:WiFi UDP和TCP

在上一篇文章中,我们通过编写EV3 Port Viewer项目实现了iOS监测EV3的实时端口数据.程序最核心的部分就是我们的开源代码库iOS_WiFi_EV3_Library.那么,在本文中,我们将详细介绍我们这个库的编写.为了完成这个库,本人参考了网上很多资料,主要包括EV3的源代码,win版本的代码库以及Monobrick相关以及网上的各种资料,在此就不一一列举了.由于水平有限,本代码库还存在各种问题,望使用的读者见谅.大家也可以在这个基础之上自己进行改造完善. 为了详细说明代码库的实现,

【iOS与EV3混合机器人编程系列之三】编写EV3 Port Viewer 应用监测EV3端口数据

在前两篇文章中,我们对iOS与EV3混合机器人编程做了一个基本的设想,并且介绍了要完成项目所需的软硬件准备和知识准备. 那么在今天这一篇文章中,我们将直接真正开始项目实践. ==第一个项目: EV3 Port Viewer== 项目目的:在iOS设备上通过WiFi连接EV3并且读取EV3每个端口的数据. 大家可以一周之后在App Store上搜索EV3 Port Viewer,那么我已经做了一个范例App发布了,正在审核中 应用的基本使用要求:将EV3和iPhone同时连接到同一个WiFi网络中

【iOS与EV3混合机器人编程系列之二】工欲善其事,必先利其器(准备篇)

在上一篇文章中,我们论述了iOS与EV3结合后机器人开发的无限可能, 那么,大家要不要一起来Hacking一把呢? 为了能够完整地完成我接下来我讲的项目,我们需要做以下准备: 1.一台Mac运行MAC OS X 10.9.3以上的操作系统. 2.Xcode6.这是iOS在Mac上的开发工具.我们将使用Xcode来进行所有的项目程序的编写 3.一两个iOS设备,iPhone或iPad都行.实际上大家最好有两个iOS设备,因为最后的项目中iPhone将和EV3机器人放在一起,而用另一个iOS设备来查

【iOS与EV3混合机器人编程系列之五】iOS_WiFi_EV3_Library 剖析之连接EV3

在上一篇文章中,我们讲解了如何用开源代码库CocoaAsyncSocket来实现iOS上的UDP和TCP数据通信.那么在本文中,我们将介绍在CocoaAsyncSocket的基础如何使用UDP和TCP连接EV3的机制. 之所以我们能够通过无线连接EV3,根本原因在于EV3的源代码内建了一套无线连接通信的机制. 这套机制是这样的: 1)EV3在连接到无线网络后,就不断地从3015端口发送UDP数据,数据的格式如下: Serial-Number: 0016533f0c1ePort: 5555Name

【iOS与EV3混合机器人编程系列之一】iOS要干嘛?EV3可以更酷!

乐高Mindstorm EV3智能机器人(以下简称EV3)自从在2013年的CES(Consumer Electronics Show美国消费电子展)上展出之后,就吸引了全球广大机器人爱好者的眼球!EV3相比其上一代机器人NXT最大的提升就在于其硬件上.除了更强大的ARM处理器,并加载了Linux操作系统之外,EV3还配备了蓝牙,支持外接USB,外接WiFi.因为有了这么多的硬件提升,EV3最酷的特性在于EV3支持iOS设备!!!这使得我们可以使用iOS设备比如iPhone来控制EV3!乐高官方

【iOS与EV3混合机器人编程系列之7】通过蓝牙控制EV3

1 前言 在这个系列之前的博客中,我研究觉得在iOS未越狱的情况下,无法使用蓝牙来控制EV3,编写类似Commander的程序.但,最近和网友的研究发现,通过External Accessory 来实现蓝牙的传输比想象的简单.MFI协议的问题比想象的容易很多,关键在于我们可以获取EV3的MFI协议字符串.接下来让我们看看是怎么实现的. 2 具体代码实现 首先Apple官方有个关于External Accessory的demo 叫EAdemo,大家可以下下来,然后在plist文件中改一下协议字符串

【iOS与EV3混合机器人编程系列之六】iOS_WiFi_EV3_Library 剖析之发送命令给EV3

在上一篇文章中,我们已经知道了如何通过WiFi将iOS设备和EV3连接起来,那么下一步的工作就是从iOS设备中发送命令给EV3并接收EV3返回的数据.这也是本篇文章将告诉大家的. 首先要明确的一点是本开源代码库只封装了EV3直接命令(Direct Command),也就是无需在EV3上开发任何程序就能使用这些命令对EV3进行控制. 目前库中的API包含以下这些: #pragma mark - EV3 Direct Command // Scan or stop scan each port se

【iOS与EV3混合机器人编程一系列五个】iOS_WiFi_EV3_Library 解剖连接EV3

在上一篇文章中.我们解说了怎样用开源码库CocoaAsyncSocket来实现iOS上的UDP和TCP数据通信.那么在本文中.我们将介绍在CocoaAsyncSocket的基础怎样使用UDP和TCP连接EV3的机制. 之所以我们能够通过无线连接EV3,根本原因在于EV3的源码内建了一套无线连接通信的机制. 这套机制是这种: 1)EV3在连接到无线网络后,就不断地从3015port发送UDP数据.数据的格式例如以下: Serial-Number: 0016533f0c1ePort: 5555Nam

TCP/IP网络编程系列之四(初级)

TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的套接字.在了解TCP之前,先了解一下TCP所属的TCP/IP协议栈. 如图所示,TCP/IP协议栈共分为4层,可以理解成数据收发分成了4个层次化过程. 链路层 它是物理链接领域标准化结果,也是最基本的领域,专门定义LAN.WAN.MAN等网络标准.若两台计算机通过网络进行数据交换,链路层就负责整个物