iOS中的WiFi与硬件通信

WiFi通信是指手机通过WiFi与外部设备建立连接,并与外部设备进行交互、通信。手机与外部设备的WiFi通信通常是使用Socket来实现的,在这里先介绍一个第三方Socket库(CocoaAsyncSocket)来实现WiFi通信。

CocoaAsyncSocket支持TCP和UDP,其中:

AsyncSocket类是支持TCP的;

AsyncUdpSocket类是支持UDP的。

本文是建立在硬件通过UDP广播包广播自身信息,手机与硬件之间通过TCP连接传输数据。

WiFi连接的建立

首先,通过手动连接手机WiFi至外部设备,此时可以获取到外部WiFi的一些信息:

#import <UIKit/UIKit.h>@interface ViewController : UIViewControllertypedef void (^udpSocketBlock)(NSDictionary* dic,NSError* err);// block用于硬件返回信息的回调
@property (nonatomic,copy) udpSocketBlock udpSocketBlock;
- (void)sendUdpBoardcast:(udpSocketBlock)block;
@end
#import "ViewController.h"
#import <AsyncSocket.h>
#import <AsyncUdpSocket.h>
@interface ViewController ()<AsyncSocketDelegate,AsyncUdpSocketDelegate>
@property (nonatomic,strong) AsyncUdpSocket *udpSocket;
@property (nonatomic,strong) AsyncSocket *socket;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];
}- (void)sendUdpBoardcast:(udpSocketBlock)block{self.udpSocketBlock = block;if(!_udpSocket)_udpSocket = [[AsyncUdpSocket alloc] initWithDelegate:self];NSData *data = [NSData data];// 此处data是根据硬件要求传参数UInt16 port = 34343;// 此处具体指需询问硬件工程师[self.udpSocket enableBroadcast:YES error:NULL];[_udpSocket sendData:data toHost:@"255.255.255.255" port:port withTimeout:-1 tag:0];// 因为不知道具体的ip地址,所以host采用受限广播地址
}
- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port{
// data 接收到的外部设备返回的数据id result = [self unpackageMessage:data]; // 对数据进行处理,此处调用的 - (id)unpackageMessage:(NSData *)data ;是根据与硬件方面协商的数据格式进行的数据处理if ([[result valueForJSONKey:@"typeid"] isEqualToString:@"xxxx"]) {self.udpSocketBlock([result valueForJSONKey:@"data"],nil);} // 判断的到的数据是否为我们需要的数据return YES; // 发现设备后,则关闭发现通道return NO; // 不关闭发现通道,一直处于发现状态
}
#pragma mark - udpSocket
-(void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag{}

通过调用该方法,可以得到外部设备返还的WiFi信息:

[self sendUdpBoardcast:^(NSDictionary *dic, NSError *err) {// dic为硬件返回的参数
}];

获取硬件参数之后,需要确认手机是否已于硬件连接,直接调用方法

- (BOOL)isConnected;

若未连接,则需建立手机和硬件之间的socket连接:

- (BOOL)connectToHost:(NSString*)hostname onPort:(UInt16)port error:(NSError **)errPtr;
// hostname、port均为硬件返回的

数据的写入和读取

CocoaAsyncSocket提供了写入数据和读取数据的方法:

// 数据的写入
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
// 数据的读取
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;

数据写入具体格式需要根据硬件要求来决定,这里提供几种常用的数据类型转换方法以供参考:

  • 十六进制字符串转NSData
    -(NSData *)converHexStrToData:(NSString *)hexString {NSMutableData *data = [[NSMutableData alloc] init];unsigned char whole_byte;char byte_chars[3] = {'\0','\0','\0'};if (hexString.length%2) {//防止丢失半个bytehexString = [@"0" stringByAppendingString:hexString];}int i;for (i = 0; i < [hexString length]/2; i++) {byte_chars[0] = [hexString characterAtIndex:i * 2];byte_chars[1] = [hexString characterAtIndex:i * 2 + 1];whole_byte = strtol(byte_chars, NULL, 16);[data appendBytes:&whole_byte length:1];}return data;
    }
  • NSData转十六进制字符串
    -(NSString *) converDataToHexString:(NSData *)data
    {if (data == nil) {return nil;}NSMutableString* hexString = [NSMutableString string];const unsigned char *p = [data bytes];for (int i=0; i < [data length]; i++) {[hexString appendFormat:@"%02x", *p++];}return hexString;
    }
  • 十六进制字符串转普通字符串
    -(NSString *)stringFromHexString:(NSString *)hexString {char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1);bzero(myBuffer, [hexString length] / 2 + 1);for (int i = 0; i < [hexString length] - 1; i += 2) {unsigned int anInt;NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr];[scanner scanHexInt:&anInt];myBuffer[i / 2] = (char)anInt;}NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4];return unicodeString;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB查询报错:class com.mongodb.MongoSecurityException: Exception authenticating MongoCredential...

异常日志&#xff1a; 2019-05-30 10:10:24,252 [http-nio-8080-exec-1] DEBUG [java.sql.Connection] - ooo Connection Opened 2019-05-30 10:10:24,258 [http-nio-8080-exec-1] DEBUG [java.sql.PreparedStatement] - > Executing: insert into client_config ( appid, …

动态添加后的数据转换 — 后台接收数据

let data this.projectPersonnel.map(item > {let obj {}obj.member item.people.map(info > {return info.id})obj.member JSON.stringify(obj.member)obj.projectId idobj.teamId item.name.idreturn obj})

iOS开发--地图与定位

iOS开发--地图与定位 概览 现在很多社交、电商、团购应用都引入了地图和定位功能&#xff0c;似乎地图功能不再是地图应用和导航应用所特有的。的确&#xff0c;有了地图和定位功能确实让我们的生活更加丰富多彩&#xff0c;极大的改变了我们的生活方式。例如你到了一个陌生的地…

CTO、技术总监、首席架构师的区别

项目经理是项目的直接负责人&#xff0c;这个角色相当于一个中间接口&#xff0c;不管是团队成员还是需求方&#xff08;客户&#xff09;&#xff0c;或者是上级领导&#xff0c;有事都直接找他&#xff0c;所以这个职位着重 于管理与沟通。一般来说&#xff0c;项目经理的工作…

iview组件库 - 穿梭栏设置

<Modalv-model"modal1"title"项目药品上下架维护"width"1020":mask-closable"false"on-ok"addOk()"><Col span"36"><Selectfilterableon-change"onChangeProject"placeholder"请先…

如何优雅地使用Sublime Text3

Sublime Text&#xff1a;一款具有代码高亮、语法提示、自动完成且反应快速的编辑器软件&#xff0c;不仅具有华丽的界面&#xff0c;还支持插件扩展机制&#xff0c;用她来写代码&#xff0c;绝对是一种享受。相比于难于上手的Vim&#xff0c;浮肿沉重的Eclipse&#xff0c;VS…

题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13... 求出这个数列的前20项之和。...

题目&#xff1a;有一分数序列&#xff1a;2/1&#xff0c;3/2&#xff0c;5/3&#xff0c;8/5&#xff0c;13/8&#xff0c;21/13... 求出这个数列的前20项之和。 程序分析&#xff1a;请抓住分子与分母的变化规律。 public class 第二十题求数列之和 {public static void mai…

iview 组件 设置头像更换

基于iview 组件 设置头像更换 <!-- 头像更换 --><div style"width: 100%;height:100%;"><div style"height: 100%;"><Upload :on-success"uploadSuccess" :show-upload-list"false" accept"image/png, i…

HTML的target属性中_blank、_self、_parent、_top含义

_blank 浏览器会另开一个新窗口显示链接_self&#xff0c;在同一框架或窗口中打开所链接的文档。 此参数为默认值&#xff0c;通常不用指定。 _parent&#xff0c;将链接的文件载入含有该链接框架的父框架集或父窗口中。 如果含有该链接的框架不是嵌套的&#xff0c;则在浏览…

Windows 聚焦的锁屏壁纸设置为桌面壁纸

需求&#xff1a; Windows的锁屏壁纸偶尔遇到非常喜欢的壁纸&#xff0c;想设置为桌面壁纸。 步骤如下&#xff1a; 1. “Windows 聚焦”的锁屏壁纸都保存在隐藏文件夹 --- Assets里。 a. 打开“资源管理器 b. 在地址栏复制粘贴下方路径后按回车键&#xff0c;即可快速跳转至这…

VUE药监码扫描

<!-- 药监码 --><div class"divContent"><div class"headDiv"><div class"spanA">请扫描相关药监码</div></div><button class"scanBtn" clickscan_img()>扫描药监码</button><bu…

Chrome 控制台的console用法收集

Chrome 控制台console的用法 大家都有用过各种类型的浏览器&#xff0c;每种浏览器都有自己的特色&#xff0c;本人拙见&#xff0c;在我用过的浏览器当中&#xff0c;我是最喜欢Chrome的&#xff0c;因为它对于调试脚本及前端设计调试都有它比其它浏览器有过之而无不及的地方。…

面向对象思想封装狙击手狙击敌人

需求&#xff1a;狙击手xxx使用xx枪&#xff0c;射击敌人xxx,敌人生命值归0&#xff0c;应声倒下分析设计类&#xff1a; 封装狙击手类 属性&#xff1a; 名字 行为&#xff1a;捡枪   装弹   射击封装枪类 属性&#xff1a; 型号 行为&#xff1a;射击封装弹夹类 属性&…

JavaScript 字符串处理方法总结

变量从字符串转换成int和float型 var weightincrease "2.5kg";undefinedparseInt(weightincrease);2parseFloat(weightincrease);2.5 字符串处理方法var words "鱼神是个帅哥";undefinedwords.length6words.charAt(0);"鱼"words.charAt(words.…

【js】vue 2.5.1 源码学习(二) 策略合并

一、 整体思路1 首先是代码的大体构造&#xff0c;先判断引入代码的环境&#xff0c;即对应amd 和cmd的处理2 vue_init 需要借助 initMinxin >>> // 初始化选项1: 规范 2: 合并策略。3 mergeOptions 选项合并 一个或者多个对象合并&#xff0c;并且生成一个…

解决公众号的加载问题

相关组件内设置的方法&#xff08;方法可以多处组件运用&#xff09; <x-input on-change"changeinp" on-blur"temporaryRepair();" on-enter"temporaryRepair();" name"mobile" :show-clear"false" placeholder"…

JavaScript 数组处理方法总结

数组处理方法//定义数组var array [];undefined//查看类型typeof(array);"object"//往数组里添加数据array [first,second,third]["first", "second", "third"]//数组长度array.length3//索引array[0]"first"//添加数组新…

今天第一次开通blog

纪念第一次开通转载于:https://www.cnblogs.com/struggle-star/p/10960491.html

前端设置,验证码登录

<group class"shadow" gutter"0"><x-input v-model"mobileCaptcha" placeholder"请输入手机验证码" class"weui-vcode" keyboard"number" :max"6"></x-input><button click"…

JQuery实现页面跳转

$(function(){ var pn $("#gotopagenum").val();//#gotopagenum是文本框的id属性 location.href "NewList.aspx?pagenum"pn;//location.href实现客户端页面的跳转 }); 今天我们就来说一说如何在jQuery中跳转到另外一个网页HTML。其实下面我列举的几…