Measuring network speed
Posted: Wed Jan 08, 2025 12:55 pm
I'm making a 5G speed logger on Android for when I travel in the US and Baltics. It's not precise but it'll give precise-enough numbers for the use case, and should be good for up to 10Gbps with default variables. I mostly need it to find 1Gbps towers. It's good for measuring any net connection while conveniently/inadvertently factoring overhead and latency.
FYI: When you're in forest or surrounded by buildings you actually want the lower-frequency bands, because you'll have high-latency otherwise which reduces speed; mmWave and all the stuff over 3Ghz doesn't penetrate as well. This is why n28a/700Mhz(20Mbps) is used a lot in the Baltics.
Python CGI download-simulator on an HTTP server
The SB code
As I said not precise, but should be very close and good for finding fast cell towers on any carrier anywhere. The only tunable parts are size and chunk-size server-side. I believe speedtest.net uses location based hosts to get around ping variability, and chunk-averages or websocket-averages; you can't measure chunk times in SB, but you could go with websocket for more precision(average) and charting.
There is no CORS on Android, so you could also use Google geolocation API to get basic info about the tower, example-return:
FYI: When you're in forest or surrounded by buildings you actually want the lower-frequency bands, because you'll have high-latency otherwise which reduces speed; mmWave and all the stuff over 3Ghz doesn't penetrate as well. This is why n28a/700Mhz(20Mbps) is used a lot in the Baltics.
Python CGI download-simulator on an HTTP server
Code: Select all
#!/usr/bin/env python3
import cgi
def generate_large_file():
# Simulate 10MB download
file_size = 10 * 1024 * 1024 # 10MB in bytes
chunk_size = 300 * 1024 # 300KB per chunk
# We'll simulate a file by sending random data in chunks
while file_size > 0:
yield b"0" * chunk_size # Send 300KB of "0"s (you can replace it with any data)
file_size -= chunk_size
def main():
print("Content-Type: application/octet-stream") # Binary stream to simulate file download
print("Content-Disposition: attachment; filename=\"simulated_file.bin\"")
print("Cache-Control: no-cache") # Disable caching of the file
print("Transfer-Encoding: chunked") # We will be streaming the data in chunks
print() # End of headers
# Simulate a large file by streaming the data
for chunk in generate_large_file():
print(chunk.decode('utf-8', errors='ignore'), end="") # Send the chunk to the browser
if __name__ == "__main__":
main()
Code: Select all
Procedure HttpGetEvent(Success, Result$, UserData)
Protected speed$
If Success
;10MB/83,886,080b downloaded
;1Gbps would show as 119 MB/s and would take 0.08388608 seconds
speed$=FormatNumber(ValD(Str(10485760/((ElapsedMilliseconds()-UserData)/1000))),0,".",",")
If Len(speed$)>=9
;MB
Debug StringField(speed$,1,",")+"."+Mid(StringField(speed$,2,","),1,1)+" MB/s"
Else
If Len(speed$)>4
;KB
If Len(StringField(speed$,1,","))>2
Debug "0."+Mid(StringField(speed$,1,","),1,2)+" MB/s"
Else
Debug "0.0"+StringField(speed$,1,",")+" MB/s"
EndIf
Else
;B
Debug "0.0 MB/s"
EndIf
EndIf
EndIf
EndProcedure
HTTPRequest(#PB_HTTP_Get,"https://www.yoursite.com/speed","",@HttpGetEvent(),ElapsedMilliseconds())
There is no CORS on Android, so you could also use Google geolocation API to get basic info about the tower, example-return:
{
"cellTowers": [
{
"cellId": 170402199,
"locationAreaCode": 35632,
"mobileCountryCode": 310,
"mobileNetworkCode": 410,
"age": 0,
"signalStrength": -60,
"timingAdvance": 15
}
]
}