1. 程式人生 > >【iOS與EV3混合機器人編程系列之四】iOS_WiFi_EV3_Library 剖析之中的一個:WiFi UDP和TCP

【iOS與EV3混合機器人編程系列之四】iOS_WiFi_EV3_Library 剖析之中的一個:WiFi UDP和TCP

microsoft bsp lte lib async stop contex pop 分析

在上一篇文章中。我們通過編寫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.mGCDAsyncUdpSocket.h // 實現UDP傳輸GCDAsyncUdpSocket.m
1.UDP的使用Step 1:創建實例instanceUDP的使用通過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]




【iOS與EV3混合機器人編程系列之四】iOS_WiFi_EV3_Library 剖析之中的一個:WiFi UDP和TCP