4 G DTU、シリアルサーバなどのIoT伝送モジュールにおけるハートビートパケット、登録パケットの説明

無料無料技术资料

这篇内容可直接阅读,适合用于基础学习和検索引流。

4 G DTU、シリアルサーバなどのIoT伝送モジュールにおけるハートビートパケット、登録パケットの説明

ソース:Modbus China Network(modbus.cn) -中国をリードするModbus通信プロトコル技術コミュニティ

この記事:モノのインターネットトランスポートモジュールのハートビートパッケージとレジストリパッケージ:メカニズム、設計、および障害物除去·著者:modbus Technology Team·公開日2026- 0 7 - 0 1

要約:4 G DTU、シリアルサーバ、エッジゲートウェイなどのIoT伝送モジュールでは、ハートビートパケットと登録パケットは、接続の安定性とデバイス識別を維持するためのコアメカニズムです。この記事では、TCP KeepAlive、MQTT Keep Alive、アプリケーション層カスタムハートビートの3つのレベルシステムからハートビートメカニズムを説明します。DTU登録パッケージからクラウドプラットフォームのデバイスID認証まで、パラメータ計算式、コード例、障害物除去手順を備えています。キーワード:ハートビートパケット、登録パケット、4 G DTU、Keep Alive、MQTTハートビート、TCPライブ、デバイス登録。


SIMカードに4 G DTUを挿入し、シリアルパラメータを備え、サーバーに接続します-データが通過し、完了したと思います。一晩後、次の日、デバイスはオフラインになっていたが、信号はまだ点灯していた。再起動してください。あと数日でオフラインになります。

これは長い接続の典型的な問題です。IoTシナリオでは、デバイスは国中に分散しています。一部は遠隔地にあり、一部は地下室からにあります。通信リンクは、デバイスのシリアルポートから始まり、DTUの4 Gモジュールを介して、オペレータのNATゲートウェイを介して、パブリックネットワークを介してクラウドサーバーに到達します。このリンクのすべてのリンクは、あなたの接続を殺すことができますが、通知はありません。

この記事では、ハートビートパッケージとレジストリパッケージについて、概念だけでなく、プロジェクトで直接使用できるパラメータ、コード、障害物除去方法についても、原理から実践まで説明します。


なぜ長いリンクが切れたのか?

心拍数について話す前に、長い接続がどのように切断されるかを理解してください。理由によって異なる生存戦略があります。

キャリアNATタイムアウト。4 G DTUは、モバイルネットワークプライベートIP(10.x.x.x / 100.x.x.x)を使用し、事業者のNATゲートウェイを介してパブリックネットワークにアクセスできます。NATゲートウェイはリソースを節約するために、アイドル接続にタイムアウトを設定します。3大事業者の典型的な価値:

  • チャイナモバイル:5分
  • 中国では約2-3分。
  • 中国電信:約3-5分

NATタイムアウト時間は地域やプランによって異なりますが、基本的には2-5分です。この時間を超えてパケットが通過しないと、NATゲートウェイ上のマッピングレコードは消去されます。その後、サーバーがDTUに送信したい場合、NATゲートウェイはパケットを認識せず、直接破棄します。デバイスはまだオンラインに見えます(4 Gは正常に接続されています)が、データチャネルは死んでいます。

ファイアウォール/中間デバイス。エンタープライズネットワークの出口ファイアウォールは、通常、アイドルTCP接続をクリーンアップします。1台の産業用コンピュータはWiFi経由でイントラネットに接続され、クラウドサーバーとのModbus TCP接続を維持します。30分以上通信がない場合、中央のDeept/Huaweiファイアウォールは接続のステータスを期限切れとしてマークし、解放します。サーバーはデバイスがまだ接続されていると考え、デバイスはサーバーがまだ接続されていると考えます。これが“接続の偽”です。

機器の異常切断。フィールドデバイスの停電、4 G信号の喪失、スイッチの再起動-TCPコネクションのピアはFINパケットを受信しません。4層は信号を切断せず、アプリケーション層はそれを感知しません。ハートビート検出がなければ、サーバーは常にデバイスがオンラインであると考え、スケジューリングタスクは通常通り発行され、すべてのタイムアウトです。

TCPハーフオープン接続。TCPコネクションの一方の端が閉じられており(サーバが再起動しているなど)、もう一方の端はそれを知らず、まだkeep-alive状態にあります。これは標準的な“半オープン接続”シナリオです。


3層のアクティブメカニズム:TCP KeepAlive、MQTT Keep Alive、アプリケーション層ハートビート

異なるシナリオと粒度に対応する3つのレベルがあります。

2.1 TCPプロトコル層のKeepAlive-最下位で柔軟性が低い

TCPプロトコルスタックにはKeepAliveメカニズムがある。接続が有効になると、指定された時間内にデータ転送がない場合、オペレーティングシステムカーネルは自動的にプローブパケット(空のACK)をピアに送信し、ピアの応答を待ちます。相手がまだ生きている場合はACKを返し、死んでいる場合は複数のプローブで接続を閉じます。

Linuxカーネルには3つの重要なパラメータがある。

net.ipv4.t_keepalive_time = 7200    #最初のプローブまでのアイドル時間(秒)、デフォルトで2時間
net.ipv4.t_keepalive_intvl = 75     #プローブ間隔(秒)、デフォルトは75 秒
net.ipv 4.tcp_keepalive_probes = 9     検出回数は9回。

つまり、デフォルトでは、オペレーティングシステムがアプリケーション層に“この接続が死んだ”と通知する前に、TCPコネクションが2時間11 分 15 秒(7200 + 75 x 9)切断されるまでに接続が切断されます。IoTシナリオでは、この時間はまったく役に立ちません。デバイスがオフラインになっていることがわかると、デバイスのバッテリーは2回交換されます。

コード内の個々のソケットに短いパラメータを設定できます(Linux ≥ 2.6.3 7サポート):

ソケットのインポート

sock = sock.socket sock.AF_INET sock.SOCK_STREAM
sock.setsockopt sock.SOL_SOCKET sock.SO_KEEPALIVE 1
次の3つのパラメータはLinux 2.6.3 7以降でソケットがIPPROTO_TCPである必要があります。
sock.setsockopt sock.IPPROTO_TCP、sock.TCP_KEEPIDLE、60    # 60 秒のアイドル後に検出を開始
sock.setsockopt sock.IPPROTO_TCP、sock.TCP_KEEPINTVL、10   #10 秒ごとに検出
sock.setsockopt sock.IPPROTO_TCP、sock.TCP_KEEPCNT、3      # 3回无応答判定オフ

このように設定すると,接続切断の発見時間= 60 + 10 × 3 = 90 秒となる.

TCP KeepAliveには2つの致命的な欠陥がある。。

まず、エンドツーエンドのTCPコネクションが生きているかどうかしか検出できず、エンドツーエンドの中間デバイス(NATゲートウェイ、ファイアウォール)がコネクションをクリーンアップしているかどうかは検出できません。プローブパケットは、2つのエンドポイントのTCPスタック間でのみ流れ、NATゲートウェイを通過するときにNATマップエントリがフラッシュされない可能性があります。つまり、TCP層は接続が正常であるとみなしますが、NATはチャネルを閉じています。

第二に、2時間のデフォルト値は長すぎ、変更されたパラメータは現在のソケットでのみ有効であり、マシンはデフォルト設定に戻ります。また、パラメータ変更にはroot権限が必要であり、組み込みデバイス(DTU、シリアルサーバ)のカーネルは動的変更をサポートしていない場合があります。

したがって、TCP KeepAliveはモノのインターネットシナリオの補アシスタント段としてのみ機能し、アプリケーション層のハートビートを置き換えることはできません。

2.2 MQTTプロトコルのKeep Alive-標準化されたアプリケーション層保証

MQTTプロトコルは、CON NECTメッセージ内に秒単位の16ビットのKeep Aliveフィールドを定義しています。このメカニズムは、TCP KeepAliveよりもアプリケーション層の要件に近いです。

  • クライアントは、Keep Alive時間内に少なくとも1つの制御メッセージ(PUBLISH、SUBSCRIBE、PINGREQなど)を送信する必要があります。
  • サーバ(Broker)が1.5 × Keep Alive時間内にクライアントから何のパケットも受信しなかった場合,クライアントは切断されたとみなし,TCPコネクションを閉じて遺言メッセージ(Last Will)を実行する.
  • 同様に、クライアントがKeep Alive時間内にBrokerからパケットを受信しなかった場合、アクティブに再接続する必要があります。

MQTT 5.0では、ブローカーがCONNACKパケットでServer Keep Alive値を返すことができます。ブローカーがクライアントの推奨Keep Aliveを受け入れない場合、ブローカーは独自の値で上書きすることができ、クライアントはブローカーが返す値に従わなければなりません。

キー値の選択MQTTのKeep Aliveは大きすぎたり小さすぎたりできません。大きすぎると、デバイスがオフラインになるのに長い時間がかかります。小さすぎると、ハートビートパケットはSIMトラフィックを頻繁に消費します。実際のプロジェクトでは、MQTTのKeep Aliveは通常60-120 秒です。デバイスがバッテリ駆動の場合(NB-IoTシナリオ)は、300-600 秒まで緩和することができます。

TCP KeepAliveとの違いMQTTのKeep Aliveは、PINGREQメッセージをTCPパケットにカプセル化して送信するアプリケーション層プロトコルの動作です。NATゲートウェイはTCPパケットが通過することを認識し、マッピングエントリをフラッシュします。そのため、MQTTのKeep AliveはNATタイムアウトの問題を解決しますが、TCP Keep Aliveは必ずしも解決しません。

2.3アプリケーション層のカスタムハートビート-最も柔軟で設計が必要

お使いのデバイスがMQTTを使用せず、ベアTCP/UDPトランスポート(Modbus TCP、カスタムバイナリプロトコルなど)を使用している場合は、アプリケーション層のハートビートを自分で設計する必要があります。これは、4 G DTUおよびシリアルサーバーで最も一般的なハートビートパケットの概念です。

デザインの原則:

  1. 心拍数はできるだけ小さくする。フローはお金です。最小ハートビートパケットは1バイトです。0x48ASCIIの'H'
  2. ハートビート間隔はNATタイムアウトよりも小さくしてください。国内事業者のNATタイムアウトは最短2分であるため、心拍間隔は通常60 秒以下に設定されます。推奨は30-60 秒です。
  3. サーバーはハートビートに応答するはずです。一方通行のハートビートは、デバイスが生きていることをサーバに知らせるだけですが、デバイスは、サーバが生きているかどうかを知りません。双方向ハートビート(デバイス送信、サーバーバック)により、両端がピアツーピア状態を検出できます。
  4. 連続したN回のハートビート失敗後に再接続をトリガーする。ハートビートを失っても壊れない-時折のパケット損失はネットワークレベルで正常です。通常、3回連続した心拍無応答後に再接続プロセスをトリガーします。

AIRIOTプラットフォームのハートビートの例:デバイスは文字“Q”を定期的に送信し、プラットフォームは受信後すぐに“A”を返信する。デバイスは“A”を受信したかどうかによって接続が正常かどうかを判断します。この設計はシンプルで効果的で、4 G DTUで非常に低コストです。

ハートビート間隔の計算式:

ハートビート間隔NATタイムアウト時間×セキュリティ係数
セキュリティ係数= 0.6 ~ 0.8

オペレータのNATタイムアウトが5分(300 秒)の場合、セキュリティ係数は0.6、心拍間隔は180 秒以下となります。時折のネットワークジッタを考慮すると、実際のプロジェクトでは60 〜 90 秒を設定する方がセキュリティです。


TCP KeepAlive vsアプリケーション層ハートビート:どちらを使用するか?

この質問には標準的な答えはなく、シナリオによって異なります。

ディメンションDimensionTCP KeepAliveアプリケーション層ハートビート
実現コスト1行のコードオープン、プロトコルオーバーヘッドゼロハートビートフレームとタイムアウトロジックの定義が必要
NATの通過いいえ、プローブパケットは空のACKです。NATマップを更新する
柔軟性がある。TCP接続のみを検出ステータス情報、タイムスタンプ、設備電力などを携帯可能
クロスプロトコル共通TCPのみTCP / UDP対応
トラフィックオーバーヘッド非常に小さい(空のACK、約40バイト)カスタムプロトコルに依存する(通常数十バイト)
デフォルト構成2時間以上は不可。完全に制御可能。

推奨される組み合わせ戦略本番プロジェクトでは、TCP KeepAlive(基盤となるバックストップとして)とアプリケーション層のハートビート(メイン検出として)を同時にオンにします。TCP KeepAliveパラメータは短く設定されています(アイドル60 秒+ 10 秒間隔+ 3プローブ)。アプリケーション層のハートビートは30-60 秒です。バグのためにアプリケーション層のハートビートが送信されなかった場合でも、TCP KeepAliveは90 秒後に切断を検出します。

デバイスがUDPを実行する必要がある場合(一部のDTU登録モードなど)、TCP KeepAliveはまったく役に立ちません。アプリケーション層のハートビートのみを使用します。


登録パッケージ:サーバーに“自分が誰か”を知らせる

ハートビートは“私はまだ生きている”という問題を解決し、登録パッケージは“私は誰なのか”という問題を解決する。

4.1登録パッケージの性質

DTUおよびシリアルサーバでは、登録パケットは、TCP接続を確立した後にデバイスが送信する最初のデータパケットであり、サーバに自身の身元を宣言するために使用されます。サーバは、登録パケットの内容に基づいて、現在のTCPコネクションを事前登録されたデバイスレコードに関連付ける。

典型的なDTU登録プロセス:

  1. DTU電源オン、ダイヤルアップ、4 Gネットワーク接続
  2. DTUはTCP経由でサーバの指定ポートに接続します
  3. 接続が成功すると、DTUは登録パケット(カスタム文字列またはIMEI/ICCID)を送信します。
  4. サーバは登録パッケージを解決し、デバイスの身元を識別し、デバイスのステータスを更新する
  5. 登録完了、通常の双方向データ転送開始

4.2登録パケットの2種類の送信タイミング

一部のDTUは2つの登録パケット送信方法をサポートする。

接続時に送信TCPコネクションが確立されたときにのみ送信されます。その後、通常のデータ転送は登録情報を含まない。これは、サーバーが接続ごとにデバイスIDを管理するシナリオに当てはまります。TCP接続はデバイスに対応し、接続が確立されるとIDが決定されます。

各パケットの前に追加各トランスポートデータの前に登録パッケージを追加します。複数のデバイスが同じシリアルポートサーバまたはゲートウェイを介してアクセスされるシナリオに適しています。サーバは、各パケットの登録情報からデータソースデバイスを判断する必要があります。欠点は、データパケットあたりのオーバーヘッドの増加です。

有人 DTUを例にとると、登録パッケージの設定方法を使用します。

  • “Enable Registration Package”を選択
  • 送信方法:“接続時に1回送信”または“サーバに送信する各パケットの前に追加”
  • 登録パッケージの内容のカスタマイズ例011号機は、022号機)。
  • サーバが受信するデータの形式は次のとおりです。登録パッケージ+透過データ

4.3登録パッケージのデータコンテンツ設計

登録パッケージの内容は、バックエンドアーキテクチャによって異なります。一般的な実践:

IMEIをデバイス固有のIDとして使用。IMEI(国際移動機器識別番号)は、世界で唯一の15桁の数字で、4 Gモジュールでは変更できません。DTU起動時にモジュールのIMEIを読み込み,登録パッケージとしてサーバに送信する.利点は自然でユニークで、人工的な割り当てを必要としないことです。欠点は、極端なトラフィックを節約する必要がある場合は、プラットフォーム側の短いID(2-4バイト)を事前に割り当てて検討することができます。

プラットフォームで事前に割り当てられたシリアル番号を使用。デバイスをクラウドプラットフォームに登録すると、プラットフォームは一意のシリアル番号(自己インクリメンタルIDまたはUUIDの短いハッシュ)を生成します。DTUは設定ツールで書き込み、DTU接続時にこのシーケンス番号を送信します。利点は、シーケンス番号が制御可能で(例えば、リージョンによるコーディング)、長さが短いことです。欠点は、設定された配布プロセスが必要です。

ICCIDの使用。SIMカードのICCIDも20桁の番号であり、ユニークです。SIMカードは交換可能であり、デバイスはカード交換の結果として“別のデバイス”になるべきではないため、一般的には推奨されません。

4.4クラウドプラットフォームのデバイス登録とDTU登録パッケージの関係

Huawei Cloud IoTDAやAlibaba Cloud IoTなどの標準的なIoTプラットフォームでは、デバイス登録は独立したプロセスです。

  1. プラットフォーム上で製品を最初に作成する(デバイスのデータモデルを定義する)
  2. 次に、デバイスを登録します(プラットフォームはデバイスIDとデバイスシークレットを生成します)。
  3. これらの認証情報をデバイスのファームウェアまたは構成ファイルに書き込む
  4. デバイスが起動すると、デバイスIDとシークレット(通常はMQTTのユーザー名/パスワードフィールドまたはX.50 9証明書)を介してプラットフォームへの認証接続が開始されます。

このプロセスでは、DTUの“登録パッケージ”は、実際にはプラットフォームに対応するデバイス認証情報です。例えば、AIRIOTプラットフォームでは、デバイスがTCP接続を確立した後にシリアル番号を送信する必要があり、本質的にはデバイス認証プロトコルの簡略版です。

バックエンドサーバーを自分で開発した場合登録契約は完全にあなた次第です。コア要件は2つあります:一意のデバイスIDとサーバーは身元を確認できます。最もシンプルなソリューション-4 G DTUは、IMEI登録+ 固定鍵HMAC署名を使用しており、非金融グレードのセキュリティ要件を持つほとんどの産業シナリオに十分です。


V.完全なパラメータ推奨と運用構成

5.1ハートビートパラメータの推奨値

シーンはこちらハートビート間隔ハートビートタイムアウト連続失敗説明書は
4G DTU透過伝送TCP30 〜 60 秒3回(90 ~ 18 0秒)NATタイムアウトへの対応とトラフィックの両立
4G DTU透過伝送UDP15 〜 30 秒5回(75-150 秒)UDP接続なし、より頻繁なハートビート
MQTT(WiFi/イーサネット)60秒から120 秒1.5×KeepAliveMQTTプロトコル仕様に準拠
NB-IoT /バッテリー駆動300 〜 600 秒2回(600-1200 秒)省電力優先、オフライン検出時間の延長を受け入れる
Modbus TCPゲートウェイ120 ~ 30 0秒3回。有線ネットワークは安定し、緩和可能
WiFiシリアルサーバー30 〜 60 秒3回。WiFiは有線よりも高い確率

5.2 Linuxサーバ側TCP KeepAliveパラメータの推奨

そこには/etc/sysctl.conf中には

net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 3

そしてその後、sysctl -pアプリケーション。アプリケーション層の心拍数(60 秒間隔など)に加えて、2つの保証層は互いにカバーします。

5.3 DTUの実際の構成例

以下は、典型的な4 G DTU構成シナリオです(有人USR-G 780の例)。

ハートビートパッケージ:有効化
心拍周期:60 秒。
ハートビート内容Qカスタム文字列

パッケージ登録:有効化
登録パケット送信方式:接続時に1回送信
登録パッケージの内容:IMEI(デバイスのIMEIを一意の識別子として使用)

接続の種類:TCPクライアント
サーバーアドレス:your-server.com
サーバポート数:80 0 1
切断リリンク:有効、10 秒、最大30回リンク

サーバ侧対応ロジック

  1. TCP接続要求の受信→接続を
  2. 5 秒以内に登録パッケージを受け取る→ IMEIを抽出し、データベースに一致するデバイスのリストを確認→デバイスのオンラインステータスをOnlineに更新
  3. 5 秒以内にパケットを受信しない→不正接続と判断し、ソケットを閉じる
  4. 登録成功後、ハートビートタイマーを起動し、60 秒ごとに“Q”→“A”を受信することを期待します。
  5. 3つのハートビートサイクル(180 秒)で“Q”を受信しない→デバイスがオフラインになったと判断し、再接続/アラームをトリガー

6.心拍数と登録の共通穴

6.1 NATタイムアウトとハートビート周期の不一致

最も一般的な問題:ハートビートは5分で、キャリアNATタイムアウトは2分です。その結果、各ハートビート間隔でNATが切断され、ハートビートパケットが送信されず、デバイスは常に“接続→2分後に切断→ハートビートタイムアウト再接続→接続→2分後に切断”の無限ループにあります。

診断方法:サーバー側で同じデバイスの接続確立時間と切断時間を見て、切断時間-確立時間がほぼ毎回固定値(120 秒など)であれば、基本的にNATタイムアウトの問題です。

心拍数は120 秒です。

6.2登録パケットが接続の確立後すぐに送信されなかった

DTUがTCP接続を確立した後、最初に登録パケットではなく透過データを送信した場合、サーバはそのデータがどのデバイスから来たのかを認識できません。特に、複数のデバイスがサーバポートを共有している場合、最初に受信したデータパケットが登録パケットでなければ、サーバは接続を破棄または閉じることができます。

登録パケットがソケット接続に成功した後、最速の速度で発行されることを確認する必要があります。

6.3心臓は片方だけです。

デバイスがハートビートを送信し、サーバーが応答しない-サーバーはデバイスが生きていることを知っていますが、デバイスはサーバーが生きていることを知りません。プログラムのバグやネットワークの問題によりサーバーがハートビートに応答しなくなった場合、デバイスはビジネスデータの送信がタイムアウトするまで待ち続ける可能性があります。

双方向ハートビートにより、デバイス側はサーバーの異常を積極的に検出し、再接続をトリガーできます。全国に分散した無人DTU機器にとって、これは重要です。

6.4 TCP KeepAliveのクロスプラットフォームの違い

Windows、Linux、Free RTOS、LwIPではTCP KeepAliveのデフォルト値と設定可能なパラメータが異なります。Linuxはデフォルトで7200 秒、Windowsはデフォルトで7200000ミリ秒(2時間)、LwIP(組み込みTCPプロトコルスタック)もデフォルトで大きいです。デフォルト値に頼らないでください。

6.5登録パッケージが検証されません。

登録パケットが平文で送信された場合(IMEIを直接送信するなど)、ネットワークリンク上でパケットを改ざんする可能性があります。セキュリティ要件の高いシナリオでは、登録パッケージに少なくとも1つのダイジェストまたは署名が必要です。最も簡単な方法:デバイスは事前に設定された対称キーでIMEI +タイムスタンプをHMACし、サーバーはHMACが承認された後に登録を受け入れる。


7.チェックリストのチェック

DTUが頻繁にオフラインになる場合は、次の順序でチェックします。

ステップはチェック項目方法論は予想通り
1心臓は本当に鼓動するか?サーバ側のログ/パケットのキャプチャ設定した心拍周期で安定受信
2ハートビート間隔vs NATタイムアウトハートビートサイクルとキャリアNATタイムアウトの比較ハートビートサイクルNATタイムアウト× 0.6
3サーバがハートビートに応答するかどうか機器側の記録“Q”を出して“A”を受け取る
4切断後の自動再接続SIMカードを取り外し、再度挿入。DTU自動再接続+登録パケットの送信
5登録パッケージを最初に送るかどうかTCPコネクションが確立された後の最初の数パケットをキャプチャする最初のパケットは登録パケットです。
6サーバ側TCP KeepAliveパラメータ{{さーば侧 TCP KeepAliveぱらめーた}}`sysctl net.ipv4.tcp_keepalive_time`120 秒です
7オペレータ信号強度DTU ATコマンド`AT+CSQ`15以上(10未満の不安定)
8SIMカードの有効期限/延滞キャリアバックグラウンド検索十分なトラフィック、遅延なし

ハートビートと登録パッケージの概念はシンプルです。パケットを定期的に送信し、自分が誰であるかを示します。しかし、実際には、詳細はパラメータ選択と故障モードの予測にあります。この記事で与えられた数字(30 秒、60 秒、120 秒)はカジュアルに書かれたものではありません。国内3大事業者のNATタイムアウト、4 Gモジュールの消費電力制約、およびサーバーリソースのオーバーヘッドのバランスに基づいています。シナリオが異なる場合は、テスト環境で独自のパッケージをキャプチャして検証します。

再び話す問題がある。

この資料を実際のプロジェクトに活用しませんか?

ツールセンターで電文解析、CRCチェック、デバイスデバッグを行うか、要件を送信して選定と接続のアドバイスを受けましょう。

エンジニア会員

この記事を実行可能なデバッグ資料に

登録すると、高度な電文解析、資料パックのダウンロード、コード例、エンジニアリングケース、優先技術サポートが利用可能に。実際のプロジェクト納品に最適です。

高度なツール無制限
資料パックとコードパック
完全なエンジニアリングケースライブラリ
優先技術サポート窓口

发表回复

あなたのメールアドレスアドレス不会被公开。 必須項目已用 * 标注