Easy way to simulate a slow network in python

Scenario. I have a client with two network connections to the server. One connection uses a mobile phone, and the other uses a wlan connection.

The way I solved this is that the server is listening on two ports. But the mobile connection should be slower than the wlan connection. The data that is sent is usually a string of text. I solved the problem of a slow connection by allowing the mobile connection to send data in five seconds, the wlan connection has an interval of one second.

But is there a better way to slow down? Perhaps sending smaller packets, i.e. I need to send more data?

Any ideas on a good way to slow down one of the compounds?

Orjanp

A simple example of a single connection client.

def client(): import sys, time, socket port = 11111 host = '127.0.0.1' buf_size = 1024 try: mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mySocket.connect((host, port)) except socket.error, (value, message): if mySocket: mySocket.close() print 'Could not open socket: ' + message sys.exit(1) mySocket.send('Hello, server') data = mySocket.recv(buf_size) print data time.sleep(5) mySocket.close() client() 

A simple server listening on a single port.

 def server(): import sys, os, socket port = 11111 host = '' backlog = 5 buf_size = 1024 try: listening_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) listening_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) listening_socket.bind((host, port)) listening_socket.listen(backlog) except socket.error, (value, message): if listening_socket: listening_socket.close() print 'Could not open socket: ' + message sys.exit(1) while True: accepted_socket, adress = listening_socket.accept() data = accepted_socket.recv(buf_size) if data: accepted_socket.send('Hello, and goodbye.') accepted_socket.close() server() 
+6
python networking network-programming
source share
3 answers

Besides using an external tool to simulate the type of network you are interested in, one good approach is to use a replacement socket implementation.

This assumes that the socket design is a parameter for your function, instead of importing the socket module and using it directly. For normal operation, you will pass a type of real socket, but if you want to test various adverse network conditions, you can pass an implementation that mimics these conditions. For example, you can create a socket type that parameterizes latency and throughput (untested code, beware):

 import time, socket class ControllableSocket: def __init__(self, latency, bandwidth): self._latency = latency self._bandwidth = bandwidth self._bytesSent = 0 self._timeCreated = time.time() self._socket = socket.socket() def send(self, bytes): now = time.time() connectionDuration = now - self._timeCreated self._bytesSent += len(bytes) # How long should it have taken to send how many bytes we've sent with our # given bandwidth limitation? requiredDuration = self._bytesSent / self._bandwidth time.sleep(max(requiredDuration - connectionDuration, self._latency)) return self._socket.send(bytes) 

If you implement other socket methods, connect, recv, etc., you can replace an instance of this class with an instance of a real socket type. This leaves the rest of your program completely free from any knowledge of your simulation, simplifying it, and also allowing you to try many different network configurations, simply by introducing a new type of socket that simulates them.

This idea is one of the reasons why Twisted explicitly shares the idea of ​​“protocols” - objects that can interpret bytes from the network and generate new bytes to send to the network — from “transports” - objects that know how to get bytes from the network and put bytes on it. Separation makes testing easier and allows you to create new configurations like this one, where the simulation of some other network conditions (which can be difficult for real) is provided by transport.

+9
source share

If you do not answer the question you asked, I would look for software that does this at a lower level.

Netlimiter does this for Windows. I think BWMeter and Bandwidth Controller can do this too.

pyshaper is a similar tool for Linux. Open source. You can simply import it into your Python program.

(Another thing to keep in mind is that you may have a router capable of generating traffic the way you want. It's a pretty big dependency to add to your software, and it may be more work to configure.)

+4
source share

Well, what makes a network connection “slower” than another is due to latency and / or bandwidth. Therefore, if you want to have a realistic simulation, you need to find the bandwidth of your mobile phone, as well as its delay and simulate it in your client program.

But you seem to imply that you are sending very little data, so bandwidth will probably not affect the speed of your connection. That way, you can simply simulate latency and do what you do: sleep (latency) between every packet you send. 5 seconds seems to be a lot.

But if you think bandwidth might be relevant, it's actually pretty easy to simulate: bandwidth is the maximum number of bytes per second you can send, and latency is the time it takes to reach your destination.

How to do it: have a global timestamp “blocked”, representing the time until your connection is free to send data. Initialize to 0 at the beginning of your program, as we assume that it is not yet in use. Then each time you have a package to send, if "_blockedUntil" is less than now (), install it now (). Then calculate the time it takes to write your dummy "wire" by doing: packet.size () / bandwidth, which will give you the length of time, add a delay and add it to the "blocked" one.

Now calculate dt = blockUntil - now (), add the packet to the queue and add a timer to "dt", which pops the first packet in the queue and sends it.

There you go, you simulated bandwidth and latency.

Edit: as someone mentioned about dropped packages as well. You can simulate this with the likelihood of dropping packets. Note. This is only possible when manipulating packets from an unrelated protocol such as Ethernet or UDP. For example, in the case of TCP, this will not work.

+2
source share

All Articles