我猜你们看到 吐槽 两个字就会进来的。。。
撸了个高仿 Ubuntu 不带参数的 ping 程序。这里: https://github.com/Damnever/dping
撸的过程中考虑到一个问题,就是计算丢失率的时候,如果发送了一个报文,发送的报文计数(就叫 transmitted )加一,接受到一个报文,接受到的报文计数(就叫 received )加一。如果发送了一个报文并且 transmitted 加一, 如果此时按下Ctrl + C
,假设发完这个之后是一定能收到响应报文的,那么 received 就会比理论值少一,丢失率就变大。
当时就想 Python 是否能阻塞 SIGINT ,结果大失所望。。。最后我这种 C 语言学渣还得强行撸点 C 代码,反正是能用。。。 除了运行效率这种人人皆知在脚本语言中不算大槽点的问题, Python 终于让我失望了。。。
1
jiang42 2015-11-19 16:14:19 +08:00 via iPhone
为什么不把你尝试的方法发出来呢?为什么不谷歌一下呢?其实你让我挺失望的。
|
2
clino 2015-11-19 16:16:57 +08:00
看不懂楼主上面关于丢失率的那些描述...
|
3
Damnever OP @jiang42
。。。不知道你仔细看没 Google 了,要不然我怎么会说我失望。源码就是上面那个链接,把 C 代码发一遍吧 https://github.com/Damnever/dping/blob/master/dping/_sigpending.c |
4
Damnever OP @clino
如果发了一个包, transmitted 就加一,你`Ctrl + C`中断程序,你就收不到响应了, 假设这个响应是一定能收到的,不会丢失,但是程序已经挂了,那么 received 就比理论上少一,那么丢失率 (transmitted - received) / transmitted 就比理论上大一点。 |
5
9hills 2015-11-19 16:20:45 +08:00
最简单的办法难道不是直接丢弃最后一个报文的计数么。。
你的场景不就是 run 一个 ping ,然后中途 ctrl+c 导致计数有 1 的误差 |
6
felixzhu 2015-11-19 16:20:49 +08:00
楼主做这个的目的是什么?系统的 PING 实现也是无视掉了最后一个包啊。
➜ ping www.baidu.com PING www.a.shifen.com (61.135.169.125): 56 data bytes ^C --- www.a.shifen.com ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss |
8
lhbc 2015-11-19 16:23:36 +08:00
把发送数用两个计数器不就行了
send 发出数 transmitted timeout 或 received 后 +1 然后直接计算 received / transmitted |
9
zjq426 2015-11-19 16:27:07 +08:00
python 按下 control+c 不是会抛出一个 KeyboardInterrupt 异常么,如果只是想正常中止可以捕获这个并处理。如果是要处理 signal 貌似也可以通过 signal.signal 库来注册你的 handler.
http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python |
13
jiang42 2015-11-19 16:36:59 +08:00 via iPhone
@Damnever 再去看看提问的艺术
我看了 readme ,如果是你 readme 里那种情况的话 https://gist.github.com/anonymous/c92e30504540a28c2788 |
16
mengzhuo 2015-11-19 16:42:33 +08:00 via iPhone
跟语言没干系啊,这都啥奇葩需求
你都终止进程了 还想让死人干什么? |
17
est 2015-11-19 16:42:44 +08:00
LZ 试试这个呀 http://stackoverflow.com/a/1112350
|
22
jiang42 2015-11-19 16:51:10 +08:00 via iPhone
@Damnever 我确实没有 get 到,你提供一个你的程序可以而我的程序不行的 testcase 呗
|
24
scenix 2015-11-19 17:01:04 +08:00
https://docs.python.org/3/library/signal.html 楼主我在这里看到有个 signal.sigpending()的函数,不知道你用不用的上。
|
25
clino 2015-11-19 17:01:58 +08:00
楼上 @9hills 说的是对的"最简单的办法难道不是直接丢弃最后一个报文的计数么。。 " 合理
因为你的程序已经终止,这最后一个报文你是没办法知道到底对不对的,所以不能计算最后这一个 |
28
jiang42 2015-11-19 17:09:26 +08:00 via iPhone
@Damnever 有点懂了,不过在我看来实现你的需求不需要 block 。 Python 2 的文档里明确说明不支持 block 。 Python 3 提供 signal.pthread_sigmask 。我不知道你用的 Python 版本,不过是时候抛弃 2 了
|
30
jiang42 2015-11-19 17:17:06 +08:00 via iPhone
@Damnever 其实,就是这样的。。。不然要 C API 干嘛。。。你可以提交 patch 啊,反正是开源的。。。我看了下,似乎 ruby 也不能 block 。。。
|
31
CRVV 2015-11-19 23:33:28 +08:00
确实看到吐槽就进来了,于是进来吐槽
1 、 A simple ping program written in Python 2 、费了这么大的劲,如果有个包在第 4 秒回来了,你这程序还是没把丢包率算对 3 、实现这个需求显然有简单得多的方法,上面也有人说了。你就非要搞这个 SIGINT ,于是成功地把简单的问题复杂化了 4 、有 Python3 不用,还 from __future __ import xxx , 明摆着自己给自己找麻烦 |
32
Damnever OP @CRVV
感谢吐槽,首先,第一二点我同意;然后第三点我实际上也在吐槽我自己,学习阶段给自己挖点坑没什么不好,但不能知难而退;第四点,我是为了把 2 和 3 都给兼容了,你认为这种小程序还这样就是找麻烦,我也没辙。。。 |