Method_Confusion_Attack_on_Bluetooth_Pairing

2023-05-16

Method Confusion Attack on Bluetooth Pairing | IEEE Conference Publication | IEEE Xplore

引言

本文讲述一种蓝牙配对机制的设计缺陷。此漏洞允许两个设备使用不同的方法执行配对。在成功相互交互时,被攻击的设备并不知道方法混淆。此攻击即使在蓝牙的最高安全模式下也适用(MITM保护下)。通过方法混淆攻击,攻击者可以渗透受害者之间的安全连接并拦截/监控所有流量。

蓝牙会根据应用程序请求提供加密、身份验证和完整性保护。为了支持这些功能,必须在参与设备之间建立可信连接。此过程(配对过程)在首次使用时建立信任。首先,用户必须启用蓝牙广播,使该设备对其他蓝牙设备可见。接下来,在其他设备上启动配对过程。在配对结束时,两个设备都相互进行身份验证并共享一个密钥,以实现加密安全的数据传输。

对于配对过程来说,有多种配对方法(关联模型)。理论上,设备之间需要在配对方法上达成一致(可能需要用户参与),但实际上可以利用某种缺陷(所提的设计缺陷),从而使用不同的方法进行配对(方法混淆)。此外,蓝牙配对无法验证两个设备是否实际执行相同的配对方法。因此,执行完全不同配对方法的两个单独配对过程可能相互作用。即使用户参与了配对过程,也没有向用户提供足够的信息来识别这种方法混淆。

攻击者主要拦截并劫持两个设备(尚未建立信任连接)之间的配对尝试。随后,攻击者对两个受害者执行两种不同的配对方法(方法混淆)。此时,受害者假设正在与他们想要的同伴配对。攻击者现在获得了秘密信息,这些信息反过来又可以用来影响配对过程,使方法混淆以成功的配对结束。虽然受害者假设已经建立了可信的连接,但他们也与攻击者进行了配对,此时攻击者现在处于稳定的中间人(MitM)位置。

BLE4.2 版本后开始支持低能安全连接(LESC,本文的攻击的主要目标)。其在曲线P-256上使用基于椭圆曲线的迪菲-赫尔曼ECDH密钥交换,此种方法对手无法通过被动窃听获取密钥。

配对过程

注:配对过程中,启动配对的是启动器I,应答设备的是响应器R

  1. 配对特征交换

在实际配对过程之前,两个设备会交换有关各自安全要求和输入输出功能(IOCap)的信息。

  1. 交换公钥

两个设备交换ECDH公钥信息并计算共享的DH密钥。—— 此时双方未验证彼此PKPK1PK2),通过这些PK建立起的共享密钥(DHK)不能受信任。

  1. 身份验证

在此阶段,之前交换的PK才会进行验证。使用哪种验证方法(关联模型)取决于此前配对特征交换中收集的信息(IOCap)。两个设备会独立的选择验证方法。

         关联模型主要有以下几种(NCPE是攻击的核心):

  • Just WorkJW,仅工作):密钥不会经过身份验证。
  • Out of BandOOB,带外):PK通过独立于蓝牙的反向通道(NFC、二维码)进行身份验证。
  • Numeric ComparisonNC,数字比较):用户在两台设备上都会显示一个6位数字,用户需要确认它们是否相等。
  • Passkey EntryPE,密钥输入):用户在一台设备上显示一个6位数密钥,并被要求将其输入到另外一台设备中。

实际上并没有任何阶段验证双方是否使用了相同的关联模型(验证方法),正是因为这一点,才使得方法混淆攻击成为可能。(此阶段后,假定PK的完整行和真实性已经得到验证)

  1. 长期密钥计算和验证

在此阶段,受信任的PK用于双方之间建立的安全通道。

LTKMacKey来源于经过身份验证的PKMacKey 对攻击的重要性不高);f5是蓝牙规范中描述的加密密钥生成功能;NINR是在身份验证阶段交换的随机数;DHK是通过PK建立的共享密钥。

随后计算确认值EaEb,它们会通过新的安全通道进行交换,并等待对方验证。(此步骤验证之前所有交换的值的完整性和真实性)

关联模型

  1. Numeric Comparison

NC通过创建待验证的PK的哈希和来验证PK。这个哈希和在两个设备上都以6位数字的形式显示给用户。如果用户确认这些数字在两台设备上相等,则验证密钥。

这个哈希包含随机数NNR(为避免重放攻击——指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性)。这些随机数按照特定顺序进行交换,在交换前有一条确认消息。确认信息确保在他们确定自己的随机数选择之前,不会知道对方的随机数。否则,攻击者将能够轻松找到并选择导致确认值 Va 发生冲突的随机数,这会增加错误批准不合法密钥的可能性。

  1. Passkey Entry

PE要求其中一个设备选择并显示随机的6位密钥。此密钥必须由用户输入到其他设备中(具体由哪个设备显示数字,是根据IOCap选择)。

然后进行身份验证,对输入的密钥(20 bits)逐位进行验证(确保双方都拥有正确的密钥),如果该过程顺利完成,则将PK视作已通过身份验证。

  1. 协会示范协定

每个设备都有单独的功能和安全要求,为了支持各种各样的设备,会根据配对设备的功能和安全要求,动态选择关联模型(验证方法)。在BLE中,使用配对特征(IOCap)交换来商定配对方法。对于关联模型,有三个特征值需要关注:

  • OOB-bit:指示OOB数据配对。
  • MITM-bit:指示认证要求。
  • IOCaps:指示用户界面提供的IO能力。

如果每台设备都有OOB数据,那么设置OOB-bit,两者使用OOB认证方法进行配对。本文攻击不适用于OOB模式,不做讨论。

如果没有设备设置MitM-bit,可以视作双方使用JW进行配对。由于JW没有提供MITM保护,因此本文也不做讨论。

如果MitM-bit被设置,则通过IOCaps来决定使用NC还是PE配对。

  1. IOCaps
  • DisplayOnly(仅显示):设备只能显示6位数字。
  • DisplayYesNo(显示是否):设备显示6位数字,用户可以输入确认。
  • KeyboardOnly(仅输入):用户可以输入6位数字以及确认。
  • KeyboardDisplay(键盘显示):设备可以显示6位数字,用户可以输入6位数字以及确认。
  • NoInputNoOutput(无输入输出):设备无法与用户通信。

  1. 广播相关

BLE 设备的广播会从三个通道(373839)中的一个定期传输广播包。广播消息以设备地址开头,设备地址类型有:

  • 公共地址:固定;在IEEE注册。
  • 随机静态地址:固定并且随机选择;通常不会改变。

如果启用了LE隐私,还有下面几种类型:

  • 私有可解析地址:派生自公共机密(身份解析密钥(IRK));可随时更改。
  • 不可解析的专用地址:随机生成。

方法混淆攻击

方法混淆攻击针对BLE设备的配对尝试阶段(配对开始前的广播阶段),目标是实现MITM位置。攻击者会与双方设备进行R->MII->MR两个配对过程,一个通过NC方法配对,另一个通过PE方法配对(根据受攻击设备提供的 IOCap也分为了PoNNoP两种攻击)。

攻击可能成功的原因如下:

  1. 关联模型NCPE使用相同的检查形式(相同格式的数字),所以无法分辨出给定的 6 位数字是由NC配对方法产生,还是PE产生。
  2. 设备不会验证自己配对的设备使用的关联模型。
  3. 用户无法知晓自己所使用的关联模型是什么,BLE规范也没有提供这一信息,设备也不会告诉用户。

  1. 攻击流程
  1. I连接到MITM

首先需要IMR进行配对,假定用户想要配对设备RI

R 开始广播自己,I 开始搜索广播消息。同时MR也进行广播(与R同名),此时用户可以观察到MRI的配对菜单中,且MRR无法区分(同名)。为了避免R出现在I的配对菜单里,需要屏蔽R的广播信号。

  1. MITM连接到R

当配对请求到了MR后,MI会发起与R 的连接。此时IR的通信都由MMIMR)处理,而MIMR彼此共享信息,且可以访问彼此的变量和状态。

  1. PoNPasskey on Numeric

此种攻击下,IMR执行PE配对,MIR执行NC配对。下图显示了IR的具体交互过程。

        

  1. 配对特征交换

首先IMR会进行配对,进行特征信息交换:

  1. I发起与MR的配对,并传输安全需求和IOCapKeyboard)。
  2. MR响应I的配对请求,并传输安全需求(设置MITM-bit)和IOCapDisplayOnly)。

接着,触发MIR的配对,MI开始与R进行特征信息交换:

  1. MI发起与R的配对,并传输安全要求和IOCapDispalyeYesNo)。
  2. R响应MI的配对请求,并传输IOCapDisplayYesNo/DisplayKeyboard)。

  1. 交换公钥

然后,I MR 以及 MI R 同时分别的交换 PK

  1. 身份验证

首先,MR会暂停与I的配对过程(等待MIR)。同时,MIR进行身份验证(NC):

  1. 交换CRNINR(交换参数)。
  2. MIR计算Va(计算确认值)。
  3. VaR的显示屏上以6位数字呈现给用户,R等待用户比较数字完成NC验证。

接着,是IMR的身份验证(PE):

  1. MR设置自己的密钥rb = Va
  2. IMR逐位交换密钥。
  3. I请求用户输入6位密钥进行PE身份验证。

MR设置密钥rb = Va,用户在I上输入的密钥,也就是在R上显示的Va,所以在I上,ra = Va,也就可以得到ra = rb

这个过程在用户看来,就是一个合法的PE配对模式,I要求用户输入6位数字,而R上显示了6位数字等待确认。

  1. 长期密钥(LTK)计算和验证

因为IMR之前交换过PK,所以他们会计算相同的DHK(I, MR)MIR也是如此,计算出DHK(MI, R)

首先I传输其确认值EIMR收到I发来的EI后,MR会触发MI计算EMI,然后发送给R

当用户确认设备R上的NC对话后,设备完成认证阶段,等待确认消息。当R现在接收到EMI时,它成功地验证了值,并向MI回复ER。因此,RMI之间的配对成功完成。

MI收到ER后,丢弃该消息,触发MR计算EMR 然后将这个值传输给 I

I验证了收到的EMR之后,也完成了IMR之间的配对。

自此,M 能够通过解密接收到的消息,并重新加密后转发它们来中继 I R 之间的所有通信,但是IR却不能察觉攻击者的存在。

仅当两个受害者都成功完成了身份验证阶段时,才会完成LTK计算和验证阶段。如果一个受害者没有完成身份验证阶段,配对过程最终会因超时而终止。通过这种方式,攻击者可以防止所谓的单侧配对。

  1. NoPNumeric on Passkey

NoPPoN类似,唯一不同就是IMR执行NC配对,MIR执行PE配对。其攻击过程与PoN类似。

实现

本文设计了一个端到端的攻击框架,该框架共有三个组件:1)方法混淆攻击工具,2)选择干扰器,3)地址嗅探器(启用LE Privacy时使用),整个过程在蓝牙MITM平台BThack上实现。

  1. BThack

BThack是一个完善的BLE协议栈,它允许应用程序以各种方式修改通信。作者将BThackUSB Cambridge Sililcon Radio, Bluetooth Dongles (CSR的蓝牙适配器,USB接口结合。

BThack应用程序允许自定义回调,以便在某些点中断状态机的控制流(IMR等待MIR)。

凭借BTstack的单线程设计,堆栈随后暂停执行并允许内存修改,然后再最终恢复(这可以简化MitM发起方和响应方的同步)。

  1. MITM应用

BThack MitM应用程序由两个与内存无关的进程组成,分别包含独立的BLE堆栈。每个进程都与其单独的USB-BLE设备进行通信,并使用进程间通信IPC相互通信(通过IPC,它们能够同步虚拟设备的状态机和中继消息)。其中一个充当R的角色,而另一个充当I

PoN攻击的实现方式如下:I连接到MitM响应程序(MR)。这会触发MI连接R。在MR的密钥生成过程中存在一个回调。触发时,回调等待MIR完成NC,并将 Va 设置为密钥。配对完成后, I  R 之间的通信通过IPC转发。

  1. 选择干扰器

为了确保I连接到MR,而不是R,需要阻止R的广播抵达I,同时不能干到其他设备(例如MR)的广播,所以需要对广播选择性干扰。也就是说需要识别广播中的广播数据包并有选择的进行干扰,且需要低延迟的实现(需要在数据包完成传输之前,就得发送干扰消息)。

本文采用Cayre等人的方法,使用nrf51 BLE芯片上的定制固件(需要使用三个,因为广播通道有三个)的地址匹配功能。

地址匹配功能能够配置4字节模式,如果发现该模式,则会触发数据包接收过程。此功能的用途是过滤传入数据包的报头地址,以提供选择性接收。如果接收到指定的数据包的报头地址,会停止接收数据包,并切换到传输模式,传输虚拟数据包。两次同时访问介质时造成的干扰会导致广播数据包的校验和不匹配;这会导致数据包在接收时被丢弃。

所有这些操作都是在硬件中执行的,没有CPU的参与,从而保证较低的延迟。

如果未启用LE Privacy,则广播地址是固定的,匹配广播地址的前四个字节;如果开启LE Privacy,广播地址随机,作者认为可以通过匹配本地名称来实现。虽然数据包布局可变,但是在相同型号/实现设备之间是一致的。

  1. 地址嗅探器

如果LE Privacy被启用,则会使用R的本地名称进行干扰。在这种情况下,框架还初始化一个可以禁用CRC检查(检测数据传输过程中是否出现错误)的嗅探器,以跟踪受害者响应器的地址。当它上线并发布广播时,它会不断扫描R。与此同时,BThack MitM应用程序在R的本地名称下开始广播。一旦BThack MitM应用程序报告连接尝试(IMR),干扰器就会停止。然后,将R的当前地址从嗅探器传递到MitM应用程序,MitM应用程序随后在MIR之间发起连接。攻击随后完成。

评估

作者通过四个步骤评估。首先,进行预测试,检验实际方法混淆攻击的干扰功能。然后,进行完整的端到端实验室测试,证明方法混淆攻击能够获得MitM位置。随后,实现在现成的设备。最后,进行了性能评估,以测量吞吐量和延迟。

  1. 干扰蓝牙广播(测试干扰功能)

通过一系列重复实验验证干扰功能(启用LE Privacy和禁止LE Privacy)。将R设置为可发现模式,并在启动干扰系统时尝试与R的配对。结果表明在所有测试中,均没有来自R的广播抵达I

  1. 端到端实验室测试(确认了方法混淆攻击可以破环使用LESC建立的BLE连接)

方法混淆攻击存在两种攻击变体,所以也有两种测试场景:

场景1RIOCapDisplayYesNoIIOCapDisplayKeyborad;攻击方案是PoN

场景2RIOCapKeyboardOnlyIIOCapDisplayKeyborad;攻击方案是NoP

实验过程如下:将R置于广播模式,然后扫描可用设备。在扫描结果中检测到R的名称时,尝试连接到该设备。建立连接时,请求配对。当其中一个设备显示 6 位值,而另一个设备提示密钥字段时,传输并确认了该值。一旦配对导致加密连接,信息就会通过该通道进行交换。

两种情景都成功实现MitM攻击,攻击者能够窃听受害者之间交换的信息。通过将窃听的数据与受害者合法解密的明文进行比较,可以验证这一点。

  1. 真实设备

作者同样测试了NoPPoN两种攻击变体。

I是一加7 ProAndroid 9.0)、iPhone 11iOS 13.4.1)和Thinkpad W540Windows 10),这些设备的IOCap都是DisplayKeyborad

R是:

  • Samsung Galaxy Watch 42mmTizen Wearable OS 4.0DisplayKeyboardNC配对,攻击策略为PoN
  • Reiner SCT tanJack Bluetoothwireless TAN-GeneratorKeyboardOnlyPE配对,攻击策略为NoP

其他与实验过程相同,攻击者均能够完成与受害设备的配对,并达到MitM位置。

  1. 吞吐量及延迟

作者测量了吞吐量和往返时间(RTT),总体而言,所实现的连接质量可以满足大多数应用的需求(最大为300ms)。

  1. 用户测试

作者选择了40为受过高等教育并有技术研究经验的参与者进行测试,有37位的参与者完成了配对过程,并且攻击者实现了MITM;其余3位参与者没有完成配对,但40名参与者均未察觉出攻击。

(结论)用户不太可能发现两台设备执行了两个不同的配对模式:

  • 普通用户通常不清楚蓝牙规范会向他们请求哪些操作。
  • 因为没有明显的提示,用户很难发现使用了不同的关联方法,尤其是NCPE
  • 用户很难区分合法配对和被攻击过的配对之间的区别。

修复策略

  1. 强制使用某种配对方法:如果产品只是为了与供应商发行的另一台设备配对,可以分析两个产品的IOCaps,将关联模型限制为某种特定方法。
  2. 用户界面设计(提醒用户):蓝牙规范没有规定NC PE 对用户展示的特定措辞或 UI 设计。因此,可以呈现特定视觉和措辞,来提醒用户。供应商可以警告用户不要滥用所提供的信息。例如,NC 对话框可以警告用户不要在任何地方输入显示的号码。
  3. 认证关联模型:将配对所使用的关联模型信息提供给用户。

作者希望,可以通过协议本身(而不是修改协议)来防止方法混淆攻击。具体而言,就是建议PE使用的密钥必须与NC中显示的值明显可区分,例如,PE密钥的最低有效位设置为1NC密钥的最低有效位设置为0。当期待PE密钥的程序收到NC密钥时,能够检测到并中止配对。

换句话说,就是在20位中的一位设置有效位,这样虽然会减少一半的值空间(攻击者可能更有机会暴力破解密钥),但是考虑硬件功能,值空间依旧足够大。如果不遵循这些更新的准则的设备可能会有50%的可能连接失败。但是作者认为这个方案的优点大于缺点,

此解决方案的优点是很容易修改到现有协议。首先,尝试支持此功能的设备不需要实现新的输入方法。其次,协议不需要改变。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Method_Confusion_Attack_on_Bluetooth_Pairing 的相关文章

  • Android BLE 特性 getValue 在 API 级别 33 中已弃用,我获取该值的正确方法是什么?

    Android BLE 特性 getValue 在 API 级别 33 和developer android 中已弃用蓝牙Gatt特性 https developer android com reference android blueto
  • 在 Android-x86 上网本上使用 ADB 通过蓝牙调试应用程序

    我设法在我的上网本上设置了一个运行良好的 Android x86 启用了蓝牙并与我的 Windows 7 开发工作站配对 我最初希望通过 USB 使用 adb 就像我使用真正的手机一样 所以我插入了专用的 USB 公对公电缆 然后 什么也没
  • OS X 10.11 El Capitan 上的蓝牙低功耗延迟/延迟

    我一直在开发一个 Mac OS X 应用程序 该应用程序通过低功耗蓝牙连续向硬件设备发送命令 在 Yosemite 环境下 该应用程序运行良好 测得命令传输的往返延迟为 7 12 毫秒 该命令以最小 2 秒 最大 0 2 秒的稳定间隔发送到
  • 使用 Jelly Bean 的简单安全配对(蓝牙)与 NFC 配对

    截至 io2012 和JellyBean 文档 http www android com about jelly bean 现在有一种通过 NFC 配对蓝牙设备的方法 这听起来确实不错 但我找不到任何有关它的文档 我特别想知道这是否适用于不
  • 如何使用 python 从气球弹出窗口中读取文本?

    我正在使用蓝牙将大约 500MB 的大文件从一个系统传输到另一个系统 在此期间 我将看到一个气球弹出窗口 显示 蓝牙连接 并显示模式已更改为高速模式的文本 我想使用 python 将此文本获取到变量中 关于如何从气球弹出窗口中读取文本的任何
  • Windows Phone 8.1 中的信标 - 没有可能性吗?

    首先 是的 我已经阅读了所有其他类似的问题 其次 我正在开发应用程序 WP 8 1 WinRT 它必须使用信标 我读了很多相关内容 我知道 如果不先配对 通常无法与 BLE 设备连接 但希望最后会破灭 所以我想问一下我有什么可能性 可以在代
  • 从 Android 4.2 更新到 Android 4.3 后,使用蓝牙 SPP 配置文件的应用程序无法运行

    我写了一个基于bluetoothChat的简单应用程序 我使用 SPP 配置文件在手机和蓝牙模块之间进行通信 电话始终发起通信 该应用程序在 Android 4 2 Nexus 3 和 Samsung Galaxy 3 上完美运行 更新到A
  • bluez 同时具有经典和低能耗设备

    Linux下的bluez是否可以同时连接多个经典和低能耗设备 bluez 网站提供这样的信息不是很有帮助 是的 我已经成功同时连接到 7 个低能耗设备 最大值因您使用的硬件而异 您还可以连接到多个经典设备 以下是我用于通过 L2CAP 连接
  • Android 和 iOS 如何扫描蓝牙信标而不出现电池问题?

    如果我想在 Android 或 IOS 中开发自己的 iBeacon 服务 它必须实用 这意味着客户可以使用我的服务而不会出现电池短缺的情况 我认为即使 iBeacon 技术基于蓝牙低功耗 它仍然可能缺乏电池 这是因为应用程序必须始终运行才
  • 编写java代码时出现SIGSEGV

    我有一段代码在 HTC Desire HD v2 3 3 上运行得很好 但是在 HTC Desire v2 2 上运行时 关闭蓝牙套接字时会崩溃并出现 SIGSEGV 07 25 16 23 52 462 INFO DEBUG 64 07
  • iOS Swift - 使用蓝牙外部扬声器时音质较差

    我正在使用从 url 广播应用程序 流式传输的 iOS 应用程序 一旦我尝试通过外部扬声器或汽车音响系统等蓝牙设备从应用程序进行流传输 音频质量就会非常差且刺耳 当从 iOS 设备本身播放时 一切听起来都很好 扬声器和耳机 override
  • 没有 GameKit 的 iOS 蓝牙

    我已经知道使用 GameKit 我只能连接到运行相同应用程序的其他 iOS 设备 但我想连接到 Parallaz EasyBluetooth 芯片来发送和接收命令 因此我需要不同的解决方案 我想有一些针对越狱设备的库 但我不知道 你能给我一
  • 安卓蓝牙无法连接

    我遇到这个问题已经有一段时间了 但一直无法解决 我有一个 Android 应用程序 它将所有配对的设备放在列表视图中 当您单击列表项之一时 它将发起连接到该蓝牙设备的请求 我可以毫无问题地获取设备列表及其地址 问题是 一旦我尝试连接 我就会
  • 如何检查设备上是否启用了蓝牙

    我想检查设备上是否启用了蓝牙 以便应用程序可以在没有用户交互的情况下使用它 有什么办法可以做到这一点吗 我还可以分别检查蓝牙和蓝牙低功耗吗 我使用以下方法完成了此操作Radio class 检查蓝牙是否已启用 public static a
  • 如何在 Bluez/Linux 上从 GATT 服务器获取断开连接事件

    环境 Bluez 5 14 Linux 3 1 USB 可插拔 BLE 无线电 TI BLE 密钥卡 CC2541 开发套件 Linux 设备 USB BLE 无线电 我们使用 gatttool 启用 TI 密钥卡上的按键事件并开始监听事件
  • Android 2.1:如何轮询现有蓝牙连接的 RSSI 值?

    我需要知道使用 Android 2 1 手机与远程设备建立蓝牙连接的信号强度 从SDK中 我可以看到我可以在发现远程设备时确定RSSI 但我不知道如何随着时间的推移更新该 RSSI 值 有人可以帮我吗 谢谢 从 SDK 中这是获取 RSSI
  • 三星Android BLE多次读/写

    在 Samsung 4 2 到 4 3 BLE 应用程序迁移指南中 http developer samsung com ble http developer samsung com ble 它说 堆栈和 F W 的同步性质没有受到影响 那
  • 尝试从 Polar H10 获取心率变异性 [蓝牙低功耗示例 UWP]

    我正在与 Polar H10 合作 从中获取心率变异性 我在跑步蓝牙低功耗示例 https github com Microsoft Windows universal samples tree master Samples Bluetoo
  • 在 Android 中读取蓝牙 RSSI 以获取 BLE 邻近配置文件

    我目前正在为 Android 开发低功耗蓝牙接近配置文件 并且偶然发现了有关 RSSI 的问题 为了使邻近配置文件起作用 我必须每隔很短的时间就通过已连接的设备接收 RSSI 数据 正如我所做的一些研究 我了解到在设备发现过程中可以获得蓝牙
  • 蓝牙连接;无法正确发送字符串

    当我需要将字符串从服务器蓝牙套接字发送到客户端蓝牙套接字时 我的程序遇到了麻烦 只要我一次只发送一个字符串 例如聊天 一切都可以正常工作 但是如果我需要在短时间内编写更多字符串 以交换信息 则字符串将不会与客户端代码分离 例如 如果我发送

随机推荐