英文:
What exactly does `psutil.net_io_counters().byte_recv` mean?
问题
I use ExpressVPN and my physical connection is a wired Ethernet connection. I am currently connected to the VPN and in my "Control Panel\Network and Internet\Network Connections" page there is an adapter for the Ethernet and an adapter named "Local Area Connection 2" for the VPN connection.
My Windows Settings application tells me that I am connected to the internet through "Local Area Connection 2" and "Ethernet" has no internet.
I performed a little test, I closed all programs that can use the network connection, took a value of bytes_recv, then downloaded this file, which is exactly 1,073,741,824 bytes long, then took another value of bytes_recv and checked the difference:
import psutil
import requests
import sys
from io import BytesIO
def test(lan2=False):
if lan2:
bytes_recv0 = psutil.net_io_counters(pernic=True)['Local Area Connection 2'].bytes_recv
else:
bytes_recv0 = psutil.net_io_counters().bytes_recv
done = 0
r = requests.get('http://ipv4.download.thinkbroadband.com/1GB.zip', stream=True)
with BytesIO() as f:
for chunk in r.iter_content(131072):
done += len(chunk)
f.write(chunk)
sys.stdout.write('\r{}% done'.format(round(done / 1073741824 * 100, 4)))
if lan2:
bytes_recv1 = psutil.net_io_counters(pernic=True)['Local Area Connection 2'].bytes_recv
else:
bytes_recv1 = psutil.net_io_counters().bytes_recv
return (bytes_recv1 - bytes_recv0) / 1073741824
And I got the following results:
In [69]: test()
100.0% doneOut[69]: 2.161009442061186
In [70]: test()
100.0% doneOut[70]: 2.1637731716036797
In [71]: test()
100.0% doneOut[71]: 2.174186712130904
In [72]: test(1)
100.0% doneOut[72]: 1.033312937244773
In [73]: test(1)
100.0% doneOut[73]: 1.0409678984433413
In [74]: test(1)
100.0% doneOut[74]: 1.0346684455871582
If I don't set pernic
, it is evident that the data is somehow double counted, and indeed if I check psutil.net_io_counters(pernic=True)
then both 'Local Area Connection 2' and 'Ethernet' will change over time (all other interfaces don't change).
If I only check 'Local Area Connection 2' interface, then the result is more like it, but not quite. During the check, I am quite sure there is only exactly 1GiB of data received, but the difference is a little bit over it, and the 'errin', 'errout', 'dropin', and 'dropout' counts didn't change.
I don't know why the number is slightly bigger than expected, however, I know in telecommunications smaller chunks of data are encoded in larger chunks so that there is a little bit of overhead, and this number seems similar to 64b/66b encoding, but if that is the case then the number should be close to 1.03125, the numbers don't quite match up.
Why is the difference bigger than expected?
英文:
I use ExpressVPN and my physical connection is a wired Ethernet connection. I am currently connected to the VPN and in my "Control Panel\Network and Internet\Network Connections" page there is an adapter for the Ethernet and an adapter named "Local Area Connection 2" for the VPN connection.
My Windows Settings application tells me that I am connected to the internet through "Local Area Connection 2" and "Ethernet" has no internet.
I performed a little test, I closed all programs that can use the network connection, took a value of bytes_recv, then downloaded this file, which is exactly 1,073,741,824 bytes long, then took another value of bytes_recv and checked the difference:
import psutil
import requests
import sys
from io import BytesIO
def test(lan2=False):
if lan2:
bytes_recv0 = psutil.net_io_counters(pernic=True)['Local Area Connection 2'].bytes_recv
else:
bytes_recv0 = psutil.net_io_counters().bytes_recv
done = 0
r = requests.get('http://ipv4.download.thinkbroadband.com/1GB.zip', stream=True)
with BytesIO() as f:
for chunk in r.iter_content(131072):
done += len(chunk)
f.write(chunk)
sys.stdout.write('\r{}% done'.format(round(done / 1073741824 * 100, 4)))
if lan2:
bytes_recv1 = psutil.net_io_counters(pernic=True)['Local Area Connection 2'].bytes_recv
else:
bytes_recv1 = psutil.net_io_counters().bytes_recv
return (bytes_recv1 - bytes_recv0) / 1073741824
And I got the following results:
In [69]: test()
100.0% doneOut[69]: 2.161009442061186
In [70]: test()
100.0% doneOut[70]: 2.1637731716036797
In [71]: test()
100.0% doneOut[71]: 2.174186712130904
In [72]: test(1)
100.0% doneOut[72]: 1.033312937244773
In [73]: test(1)
100.0% doneOut[73]: 1.0409678984433413
In [74]: test(1)
100.0% doneOut[74]: 1.0346684455871582
If I don't set pernic
, it is evident that the data is somehow double counted, and indeed if I check psutil.net_io_counters(pernic=True)
then both 'Local Area Connection 2'
and 'Ethernet'
will change over time (all other interfaces don't change)..
If I only check 'Local Area Connection 2'
interface, then the result is more like it, but not quite. During the check I am quite sure there is only exactly 1GiB of data received, but the difference is a little bit over it, and the errin
, errout
, dropin
& dropout
counts didn't change...
I don't know why the number is slightly bigger than expected, however I know in telecommunications smaller chunks of data are encoded in larger chunks so that there is a little bit overhead, and this number seems similar to 64b/66b encoding, but it that is the case then the number should be close to 1.03125, the numbers don't quite match up.
Why is the difference bigger than expected?
答案1
得分: 0
Since no one bothered to answer the question I will answer my own question.
It is evident that the number 1.03125 isn't a coincidence and my network indeed uses 64b/66b line encoding.
Having said that the numbers I obtained are still a little bit over 1.03125, however I performed the test multiple times and averaged the proportion of the extra bit, and the difference is quite small:
100.0% doneOut[83]: 0.0020151299734910144
There is about 0.2% overhead, which is about 2.0635 MiB of extra data (per 1 GiB transferred payload), which is quite close to 2.048 MiB.
There might be other applications that were using the network I didn't account for, or the 0.2% overhead is caused by the encryption.
I think the extra overhead is caused by the encryption, but I am not sure, it is quite hard to connect to a VPN in my network so I didn't bother to disconnect and check.
Since the number is so small I would not try to correct it for fear of over-correcting. But the 1.03125 bit will be taken into account when doing calculations.
英文:
Since no one bothered to answer the question I will answer my own question.
It is evident that the number 1.03125 isn't a coincidence and my network indeed uses 64b/66b line encoding.
Having said that the numbers I obtained are still a little bit over 1.03125, however I performed the test multiple times and averaged the proportion of the extra bit, and the difference is quite small:
In [83]: sum(test(1)/1.03125-1 for i in range(16))/16
100.0% doneOut[83]: 0.0020151299734910144
There is about 0.2% overhead, which is about 2.0635 MiB of extra data (per 1 GiB transferred payload), which is quite close to 2.048 MiB.
There might be other applications that were using the network I didn't account for, or the 0.2% overhead is caused by the encryption.
I think the extra overhead is caused by the encryption, but I am not sure, it is quite hard to connect to a VPN in my network so I didn't bother to disconnect and check.
Since the number is so small I would not try to correct it for fear of over-correcting. But the 1.03125 bit will be taken into account when doing calculations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论