WiFi 一探设施间点对点通讯成功细节 走进Android P2P技术

  • 电脑网络维修
  • 2024-11-15

WiFi P2P技术

WiFi P2P(Peer-to-Peer),也被称为WiFi Direct,是WiFi联盟颁布的一个协定。准许无线网络中的设施在无需无线路由器的状况下相互衔接,经过WiFi间接成功两台设施之间的无线点对点通讯。原理与基于AP(接入点)的通讯形式相似,支持P2P的设施可以在同一个小组内互传数据,成功同屏性能。

WiFi P2P被宽泛运行于移动设施之间的文件共享、游戏联机、音乐播放等运行场景中。相较于蓝牙,WiFi P2P具备更快的搜查速度和传输速度,以及更远的传输距离。而且只有要关上WiFi即可,不须要参与任何网络或AP,即可成功平等点衔接通讯。关于须要在用户之间共享数据的运行,如多人游戏或照片共享十分有用。

WiFi P2P也存在一些安保性疑问,如用户隐衷暴露、恶意软件和病毒流传,以及侵权和违法内容的流传。为了包全用户的安保和隐衷,一些P2P网络提供了匿名化处感性能,经常使用安保搜查引擎,以及设置过滤器来阻止违法和侵权内容的共享。

Android WiFi P2P架构

在P2P架构中,定义了两种关键角色:P2P Group Owner(简称GO)和P2P Client(简称GC)。GO的作用相似于Infrastructure BSS中的AP(接入点),而GC的作用相似于Infrastructure BSS中的STA(站点)。当两台设施经过P2P衔接后,会随机(也可以手动指定)指派其中一台设施为组领有者(GO),相当于一台主机,另一台设施为组成员(GC)。其余设施可以经过与GO设施衔接参与组,但不能间接和GC设施衔接。

在Android系统中,WiFi P2P性能是在Android 4.0及更高版本系统中参与的。它可以经过WifiP2pManager类启动成功,这个类提供了许多方法来扫描可用设施、建设P2P衔接并传输数据等性能。开发者可以经过这些方法来成功设施之间的文件传输等操作。

在设施发现阶段,Android WiFi P2P经常使用Probe Request和Probe Response帧来替换设施信息。在2.4GHz的1、6、11频段上发送Probe Request帧,这几个频段被称为Social Channels。一旦Listen Channel选用好后,在整个P2P Discovery阶段就不能更改,用于极速发现周围的Group。

虽然Android WiFi P2P性能弱小,目前在Android系统中只是内置了设施的搜查和链接性能,并没有像蓝牙那样有许多运行。在实践开发中,或者须要经过软件手腕处置一些逻辑和权限疑问。

Android运行WiFi P2P成功数据传输

在Android中,WiFi P2P可以经过WifiP2pManager类启动成功。开发者可以经差错掉WifiP2pManager实例,并启动广播接受者的创立和注册,调用其余WiFi P2P的API,成功设施间的搜查、衔接和数据传输等性能。例如,指定某一台设施为主机,创立群组并期待客户端的衔接恳求,而客户端则可以被动搜查左近的设施并参与群组,向主机动员文件传输恳求。

减少权限
失掉WifiP2pManager和WifiP2pManager.Channel对象
mWifiP2pManager = getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManagermWifiP2pManager?.initialize(this, Looper.getMainLooper()) {Log.d(TAG, "Channel断开衔接")}
服务端创立群组
//服务端创立群组mWifiP2pManager?.createGroup(mChannel, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "创立群组成功")}override fun onFailure(reason: Int) {Log.w(TAG, "创立群组失败$reason")}})
客户端搜查平等设施
//客户端搜查平等设施mWifiP2pManager?.discoverPeers(mChannel, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "搜查成功")}override fun onFailure(reason: Int) {Log.d(TAG, "搜查失败:$reason")}})//经常使用异步方法(介绍经过广播监听) 失掉设施列表mWifiP2pManager?.requestPeers(mChannel) {mDeviceList.addAll(it.deviceList)if (mDeviceList.isEmpty()) {//没有设施runOnUiThread { Toast.makeText(this, "没有发现设施", Toast.LENGTH_SHORT).show() }} else {//刷新列表runOnUiThread { mDeviceAdapter.notifyDataSetChanged() }}}
衔接设施
val config = WifiP2pConfig().apply {this.deviceAddress = wifiP2pDevice.deviceAddressthis.wps.setup = WpsInfo.PBC}mWifiP2pManager?.connect(mChannel, config, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "衔接成功")}override fun onFailure(reason: Int) {Log.w(TAG, "衔接失败$reason")}})
服务端创立Socket启动数据读写
// 将数据发送给客户端//须要创立子线程 否则在主线程网络操作间接闪退val serverSocket = ServerSocket(8888)val socket = serverSocket.accept()val inputStream = socket.getInputStream()val outputStream = socket.getOutputStream()//发送数据outputStream?.write(data)//此处为了繁难 实践须要开启线程读取 并且要有适合的提前while (!mQuitReadData) {val reader = inputStream.bufferedReader(StandardCharsets.UTF_8)val text = reader.readLine()Log.d(TAG, "读取到的数据$text")}
客户端创立Socket启动数据读写
//须要创立子线程 否则在主线程网络操作间接闪退val address: InetAddress = info.groupOwnerAddressval socket = Socket(address, 8888)val inputStream = socket.getInputStream()val outputStream = socket.getOutputStream()//发送数据outputStream?.write(data)//此处为了繁难 实践须要开启线程读取 并且要有适合的提前while (!mQuitReadData) {val reader = inputStream.bufferedReader(StandardCharsets.UTF_8)val text = reader.readLine()Log.d(TAG, "读取到的数据$text")}
class MainActivity : AppCompatActivity() {private val TAG = MainActivity::class.java.simpleNameprivate lateinit var mBinding: ActivityMainBindingprivate var mWifiP2pManager: WifiP2pManager? = nullprivate var mChannel: WifiP2pManager.Channel? = nullprivate var mDeviceList = arrayListOf<WifiP2pDevice>()private lateinit var mDeviceAdapter: DeviceAdapterprivate var mQuitReadData = true@SuppressLint("NotifyDataSetChanged")override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)enableEdgeToEdge()mBinding = ActivityMainBinding.inflate(layoutInflater)setContentView(mBinding.root)ViewCompat.setOnApplyWindowInsetsListener(mBinding.main) { v, insets ->val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)insets}val intentFilter = IntentFilter()intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)registerReceiver(mReceiver, intentFilter)mDeviceAdapter = DeviceAdapter(mDeviceList)mBinding.rvDeviceList.adapter = mDeviceAdaptermDeviceAdapter.mOnItemSelectedListener = object : OnItemSelectedListener {override fun onItemSelected(parent: AdapterView<*>?,view: View?,position: Int,id: Long) {val wifiP2pDevice = mDeviceList[position]connect(wifiP2pDevice)}override fun onNothingSelected(parent: AdapterView<*>?) {}}//通用步骤mWifiP2pManager = getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManagermChannel = mWifiP2pManager?.initialize(this, Looper.getMainLooper()) {Log.d(TAG, "Channel断开衔接")}//服务端局部//服务端创立群组mWifiP2pManager?.createGroup(mChannel, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "创立群组成功")}override fun onFailure(reason: Int) {Log.w(TAG, "创立群组失败$reason")}})//客户端局部//客户端搜查平等设施mWifiP2pManager?.discoverPeers(mChannel, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "搜查成功")}override fun onFailure(reason: Int) {Log.d(TAG, "搜查失败:$reason")}})//经常使用异步方法(介绍经过广播监听) 失掉设施列表mWifiP2pManager?.requestPeers(mChannel) {mDeviceList.addAll(it.deviceList)if (mDeviceList.isEmpty()) {//没有设施runOnUiThread { Toast.makeText(this, "没有发现设施", Toast.LENGTH_SHORT).show() }} else {//刷新列表runOnUiThread { mDeviceAdapter.notifyDataSetChanged() }}}}/*** 衔接设施*/private fun connect(wifiP2pDevice: WifiP2pDevice) {val config = WifiP2pConfig().apply {this.deviceAddress = wifiP2pDevice.deviceAddressthis.wps.setup = WpsInfo.PBC}mWifiP2pManager?.connect(mChannel, config, object : WifiP2pManager.ActionListener {override fun onSuccess() {Log.d(TAG, "衔接成功")mQuitReadData = falsetransferData("Hello".toByteArray())}override fun onFailure(reason: Int) {Log.w(TAG, "衔接失败$reason")mQuitReadData = true}})}private fun transferData(data: ByteArray) {//恳求设施衔接信息mWifiP2pManager?.requestConnectionInfo(mChannel) { info ->if (info.groupFormed && info.isGroupOwner) {// 将数据发送给客户端val serverSocket = ServerSocket(8888)val socket = serverSocket.accept()val inputStream = socket.getInputStream()val outputStream = socket.getOutputStream()//发送数据outputStream?.write(data)//此处为了繁难 实践须要开启线程读取 并且要有适合的提前while (!mQuitReadData) {val reader = inputStream.bufferedReader(StandardCharsets.UTF_8)val text = reader.readLine()Log.d(TAG, "读取到的数据$text")}} else {//设施是客户端val address: InetAddress = info.groupOwnerAddressval socket = Socket(address, 8888)val inputStream = socket.getInputStream()val outputStream = socket.getOutputStream()//发送数据outputStream?.write(data)//此处为了繁难 实践须要开启线程读取 并且要有适合的提前while (!mQuitReadData) {val reader = inputStream.bufferedReader(StandardCharsets.UTF_8)val text = reader.readLine()Log.d(TAG, "读取到的数据$text")}}}}private val mReceiver = object : BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {val action = intent?.action;if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {// Check to see if Wi-Fi is enabled and notify appropriate activity// 审核 Wi-Fi P2P 能否已启用val state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1)val isEnabled = (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED)} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {// Call WifiP2pManager.requestPeers() to get a list of current peers//异步方法// mWifiP2pManager?.requestPeers();} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {// Respond to new connection or disconnections// 链接形态变动回调// 此广播 会和 WIFI_P2P_THIS_DEVICE_CHANGED_ACTION 同时回调// 注册广播、衔接成功、衔接失败 三种机遇都会调用// 运行可经常使用 requestConnectionInfo()、requestNetworkInfo() 或 requestGroupInfo() 来检索衔接信息。} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {// Respond to this device's wifi state changing// 此设施的WiFi形态更改回调// 此广播 会和 WIFI_P2P_CONNECTION_CHANGED_ACTION 同时回调// 注册广播、衔接成功、衔接失败 三种机遇都会调用// 运行可经常使用 requestDeviceInfo() 来检索衔接信息。}}}override fun onDestroy() {super.onDestroy()//移除群组mWifiP2pManager?.removeGroup(mChannel, null)//敞开链接mWifiP2pManager?.cancelConnect(mChannel, null)}}

Android WiFi P2P经常使用流程总结:

在AndroidManifest.xml中申明必要的权限,包含网络访问权限和文件读写权限。

在Android运行中,首先须要失掉WifiP2pManager实例,并经过调用其initialize方法启动初始化。这将注册运行并预备经常使用Wi-Fi P2P性能。

初始化成功后,会取得一个Channel对象,它是后续操作的关键。

3.「广播接纳与处置」:

在整个环节中,运行须要注册并监听特定的广播,以处置Wi-Fi P2P形态变动、设施发现、衔接变动等事情。

这些广播会通知运行无关Wi-Fi P2P操作的形态和结果,以便运行可以做出相应的照应。

4.「设施发现」:

经常使用WifiP2pManager的discoverPeers方法开局搜查左近的Wi-Fi P2P设施。

设施会在特定的频段(如2.4GHz的1、6、11频段)上发送Probe Request帧来寻觅其余设施。

搜查到的设施会作为列表展如今运行界面上,用户可以从当选用想要衔接的设施。

5.「建设衔接」:

选定一个设施后,作为客户端或服务端(Group Owner,GO)动员衔接恳求。

经过WifiP2pConfig对象性能衔接参数,如指标设施的地址和WPS(Wi-Fi Protected Setup)设置。

经常使用WifiP2pManager的connect方法尝试建设衔接。

6.「衔接确认与数据传输」:

一旦衔接建设成功,设施之间就可以开局数据传输了。

可以经过Socket编程在设施之间建设衔接,并传输文件或其余数据。

依据运行需求,可以创立服务端套接字监听客户端的衔接恳求,也可以作为客户端被动衔接到服务端。

7.「数据传输成功与断开衔接」:

数据传输成功后,运行须要适外地封锁套接字和断开Wi-Fi P2P衔接。

经常使用WifiP2pManager的关系方法来断开衔接,并监禁关系资源。

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/7403.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号