point-source / dart_ping

Multi-platform network ping utility for Dart
30 stars 13 forks source link

Fails to parse ping output when OS language is set to Chinese #42

Closed nihai18789797273 closed 11 months ago

nihai18789797273 commented 1 year ago

I will report an error after importing

nihai18789797273 commented 1 year ago

like this : Connecting to VM Service at ws://127.0.0.1:57534/k4LafptclLQ=/ws [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FormatException: Missing extension byte (at offset 3)

0 _Utf8Decoder.convertChunked (dart:convert-patch/convert_patch.dart:1851:7)

1 _Utf8ConversionSink.addSlice (dart:convert/string_conversion.dart:314:28)

2 _Utf8ConversionSink.add (dart:convert/string_conversion.dart:310:5)

3 _ConverterStreamEventSink.add (dart:convert/chunked_conversion.dart:72:18)

4 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)

5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

8 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

9 _StreamController._add (dart:async/stream_controller.dart:648:7)

10 _StreamController.add (dart:async/stream_controller.dart:596:5)

11 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

12 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

13 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

14 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

15 _StreamController._add (dart:async/stream_controller.dart:648:7)

16 _StreamController.add (dart:async/stream_controller.dart:596:5)

17 _Socket._onData (dart:io-patch/socket_patch.dart:2355:41)

18 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

22 _StreamController._add (dart:async/stream_controller.dart:648:7)

23 _StreamController.add (dart:async/stream_controller.dart:596:5)

24 new _RawSocket. (dart:io-patch/socket_patch.dart:1877:33)

25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1334:14)

26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)

27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FormatException: Missing extension byte (at offset 1)

0 _Utf8Decoder.convertChunked (dart:convert-patch/convert_patch.dart:1851:7)

1 _Utf8ConversionSink.addSlice (dart:convert/string_conversion.dart:314:28)

2 _Utf8ConversionSink.add (dart:convert/string_conversion.dart:310:5)

3 _ConverterStreamEventSink.add (dart:convert/chunked_conversion.dart:72:18)

4 _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)

5 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

8 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

9 _StreamController._add (dart:async/stream_controller.dart:648:7)

10 _StreamController.add (dart:async/stream_controller.dart:596:5)

11 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

12 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

13 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

14 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

15 _StreamController._add (dart:async/stream_controller.dart:648:7)

16 _StreamController.add (dart:async/stream_controller.dart:596:5)

17 _Socket._onData (dart:io-patch/socket_patch.dart:2355:41)

18 _RootZone.runUnaryGuarded (dart:async/zone.dart:1593:10)

19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)

20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)

21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)

22 _StreamController._add (dart:async/stream_controller.dart:648:7)

23 _StreamController.add (dart:async/stream_controller.dart:596:5)

24 new _RawSocket. (dart:io-patch/socket_patch.dart:1877:33)

25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1334:14)

26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)

27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

flutter: PingSummary(transmitted:0, received:0), time: 0 ms, Errors: [unknown: Ping process exited with code: 1]

ckerens commented 1 year ago

This looks to be related to https://github.com/flutter/flutter/issues/81666. If you have resources in your project with non-English names, you may want to look at https://github.com/flutter/flutter/issues/81666#issuecomment-1001853875.

nihai18789797273 commented 1 year ago

这看起来与flutter/flutter#81666 有关。如果您的项目中有非英文名称的资源,您可能需要查看flutter/flutter#81666 (comment)

But this error only occurs when I use the method in this package

ckerens commented 1 year ago

Can you provide steps to reproduce the error?

nihai18789797273 commented 1 year ago

I use the instance code, which is triggered in a button. When I click the button, an error will occur,like this: image

nihai18789797273 commented 1 year ago

class _MyHomePageState extends State { @override Widget build(BuildContext context) { return TextButton( onPressed: () async { // // Create ping object with desired args final ping = Ping('google.com', count: 5);

      // [Optional]
      // Preview command that will be run (helpful for debugging)
      print('Running command: ${ping.command}');

      // Begin ping process and listen for output
      ping.stream.listen((event) {
        print(event);
      });
    },
    child: Text('测试'));

} }

nihai18789797273 commented 1 year ago

Can you provide steps to reproduce the error?

yes

point-source commented 1 year ago

What is the default language of the OS that you are running this dart application on? If it's anything other than english, you will need to specify a character encoder and a different regex parser as documented in the readme.

The reason for this is that this library actually calls the platform's ping binary and runs it as a process. It then parses/interprets the output. So it needs to know how to correctly do that.

nihai18789797273 commented 1 year ago

您运行此 dart 应用程序的操作系统的默认语言是什么?如果它不是英语,您将需要指定一个字符编码器和一个不同的正则表达式解析器,如自述文件中所述。

这样做的原因是这个库实际上调用了平台的 ping 二进制文件并将其作为进程运行。然后它解析/解释输出。所以它需要知道如何正确地做到这一点。

i see!!The default language of the operating system of this dart application is Chinese. Thank you very much

nihai18789797273 commented 1 year ago

What is the default language of the OS that you are running this dart application on? If it's anything other than english, you will need to specify a character encoder and a different regex parser as documented in the readme.

The reason for this is that this library actually calls the platform's ping binary and runs it as a process. It then parses/interprets the output. So it needs to know how to correctly do that.

I'm sorry,I have to ask you a question again. I can't understand this parser. How to modify it?

point-source commented 1 year ago

Open a command prompt or terminal on the OS (not using dart) and run a ping like this: ping google.com

Look at the output. For each line of output, you'll need to adapt the regex parser.

If you post the output of the ping command here, I can try to help you tomorrow. It's getting late here so I probably won't be able to respond much more.

nihai18789797273 commented 1 year ago

Thank you very much. Have a good rest

point-source commented 1 year ago

Can you post the output of a standard ping command on your system's terminal or command line?

nihai18789797273 commented 1 year ago

yes , this is result : C:\Users\NH-Studio>ping www.baidu.com

正在 Ping www.a.shifen.com [110.242.68.4] 具有 32 字节的数据: 来自 110.242.68.4 的回复: 字节=32 时间=12ms TTL=53 来自 110.242.68.4 的回复: 字节=32 时间=12ms TTL=53 来自 110.242.68.4 的回复: 字节=32 时间=14ms TTL=53 来自 110.242.68.4 的回复: 字节=32 时间=13ms TTL=53

110.242.68.4 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 12ms,最长 = 14ms,平均 = 12ms

C:\Users\NH-Studio>

nihai18789797273 commented 1 year ago

您能否在系统的终端或命令行上发布标准 ping 命令的输出? Can you understand? Many are Chinese

nihai18789797273 commented 1 year ago

onPressed: () { //覆盖解析器以支持替代操作系统语言,原因是这个库实际上调用了平台的 ping 二进制文件并将其作为进程运行。然后它解析/解释输出。 final parser = PingParser( //结果字符串 responseStr: RegExp(r'来自'), responseRgx: RegExp( r'de (?.*): 字节=(?:\d+) 时间=(?

nihai18789797273 commented 1 year ago

I do this, but it still gives errors

point-source commented 1 year ago

For the encoding, try it with the "allowMalformed" option:

final ping = Ping('www.baidu.com', encoding: Utf8Codec(allowMalformed: true));

nihai18789797273 commented 1 year ago

Utf8Codec

I have tried this way. Although there is no error, there is no result feedback

point-source commented 1 year ago

Okay that probably means the regex isn't picking up anything. Sorry it's taken me so long to look into this. I just have a lot going on. Thanks for your patience

nihai18789797273 commented 1 year ago

好的,这可能意味着正则表达式没有接收到任何东西。抱歉,我花了这么长时间才研究这个。我只是有很多事情要做。谢谢你的耐心

Thank you for taking the time to answer my question. Is my regex writing wrong? I tried to change the computer language to English,it can work, but I could not receive the results in Chinese

point-source commented 1 year ago

Try this:

final parser = PingParser(
    responseStr: RegExp(r'来自'),
    responseRgx: RegExp(r'来自 (?<ip>.*)的回复: 字节=(?:\d+) 时间=(?<time>\d+)ms TTL=(?<ttl>\d+)'),
    summaryStr: RegExp(r'丢失'),
    summaryRgx: RegExp(r'已发送 = (?<tx>\d+),已接收 = (?<rx>\d+),丢失 = (?:\d+)'),
    timeoutStr: RegExp(r'请求超时'),
    unknownHostStr: RegExp(r'请求找不到主机'));
nihai18789797273 commented 1 year ago

I'm sorry,Still no result

nihai18789797273 commented 1 year ago
          //覆盖解析器以支持替代操作系统语言,原因是这个库实际上调用了平台的 ping 二进制文件并将其作为进程运行。然后它解析/解释输出。
          final parser = PingParser(
              responseStr: RegExp(r'来自'),
              responseRgx: RegExp(
                  r'来自 (?<ip>.*)的回复: 字节=(?:\d+) 时间=(?<time>\d+)ms TTL=(?<ttl>\d+)'),
              summaryStr: RegExp(r'丢失'),
              summaryRgx:
                  RegExp(r'已发送 = (?<tx>\d+),已接收 = (?<rx>\d+),丢失 = (?:\d+)'),
              timeoutStr: RegExp(r'请求超时'),
              unknownHostStr: RegExp(r'请求找不到主机'));

          //发起ping
          final ping = Ping('www.baidu.com',
              count: 1,
              parser: parser,
              encoding: const Utf8Codec(allowMalformed: true));
          print('Running command: ${ping.command}');
          ping.stream.listen((event) {
            print(event);
          });
point-source commented 1 year ago

I just took the copy of your ping output and put it into here: https://regex101.com/r/aEpqAi/1

I then tried to modify the regex parser to fit the output you gave me. Since I can't read Chinese, it's possible that I over-matched some of the text. I would recommend playing around with it on regex101 to see if you can create a better parsing string. Beyond that, I'm not sure how much I can help until someone can take a look who can debug the library and reads Chinese as well.

wittDe commented 1 year ago

I debugged the code.I found out that the error comes from the decoder. I used package fast_gbk,program works fine. In my computer the console code page is 936.

// base_ping.dart

import 'package:fast_gbk/fast_gbk.dart';

// .transform(encoding.decoder)
.transform(gbk.decoder)
final parser = PingParser(
    responseStr: RegExp(r'来自'),
    responseRgx: RegExp(r'来自 (?<ip>.*) 的回复: 字节=(?:\d+) 时间=(?<time>\d+)ms TTL=(?<ttl>\d+)'),
    summaryStr: RegExp(r'丢失'),
    summaryRgx: RegExp(r'已发送 = (?<tx>\d+),已接收 = (?<rx>\d+),丢失 = (?:\d+)'),
    timeoutStr: RegExp(r'请求超时'),
    unknownHostStr: RegExp(r'请求找不到主机'),
  );
wittDe commented 1 year ago

I tried another way to solve the problem.No need to use parser. Use chcp to change the active console codepage to 437 But I'm not sure if there are other side effects.

// windows_ping.dart

...

@override
Future<Process> get platformProcess async => await Process.start(
      'chcp',
      ['437', '&&', ipv6 ? 'ping6' : 'ping', ...params, host],
      environment: locale,
      runInShell: true,
    );
...
point-source commented 1 year ago

This is actually a really neat workaround. Thanks for sharing! I'm going to look into including this natively in the package.

LailaiMaster commented 1 year ago

Thanks for the discussion.

ZaneCode6574 commented 1 year ago

I tried another way to solve the problem.No need to use parser. Use chcp to change the active console codepage to 437 But I'm not sure if there are other side effects.

// windows_ping.dart

...

@override
Future<Process> get platformProcess async => await Process.start(
      'chcp',
      ['437', '&&', ipv6 ? 'ping6' : 'ping', ...params, host],
      environment: locale,
      runInShell: true,
    );
...

Thank you. This works well.

Ampy commented 11 months ago

1.引入 import 'package:fast_gbk/fast_gbk.dart'; 2.添加代码: final parser = PingParser( responseStr: RegExp(r'来自'), responseRgx: RegExp( r'来自 (?.*)的回复: 字节=(?:\d+) 时间=(?

point-source commented 11 months ago

This should now be fixed through the use of the forceCodepage flag on version 9.0.0. Please reopen if this does not solve it for you:

final ping = Ping('google.com', forceCodepage: true);