`psutil.net_io_counters().byte_recv` 的确切含义是什么?

huangapple go评论70阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年4月11日 14:57:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75983163.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定