Max
Max

Reputation: 170

How fast are python sockets supposed to be? Why are mine running very slowly?

I've written a small program that sends some numbers over sockets. I run the client program on my computer, and the server program on a virtual machine (hosted with google cloud platform). The code I'm using:

client.py:

import socket
from time import time

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(("xx.xxx.xxx.xxx", 5555))

for i in "1234567890":
    print(f"Sending {i} at time {time()}")
    client.sendall(i.encode())

    data = client.recv(64)
    print(f"Received {data.decode()} at time {time()}")

server.py:


import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(("0.0.0.0", 5555))
s.listen(2)

print("Server listening")

conn, addr = s.accept()
print("Connected to:", addr)

while True:
    data = conn.recv(2048).decode()
    if(not data):
        print("Server closing")
        break
    conn.sendall(data.encode())

The output from client.py shows that the round trip of sending data to the server, and then receiving it and decoding it takes around 0.2 seconds. This seems rather high to me, shouldn't sockets run much faster? From this post it seems tcp sockets in java can make a round trip in 2 microseconds, which is alot faster than my 0.2 seconds. I am a newbie when it comes to sockets, so I'm not too sure about anything. If someone could provide me with some insight or maybe make a suggestion on how to enable sockets to run faster (if it's possible, maybe a different module or type of socket?) that would be great.

I started working with sockets because I wanted to make a basic multiplayer game from a tutorial that someone gave me (his sockets seem to run very fast), but after running this code, the amount of time it takes for data to go between clients seems like it would render the game non-playable, or at least severely slow and not fun at all. I did see something about using UDP instead of TCP, but after trying someone's UDP example, I found it ran just as slow.

Note:

  1. The server code is on a linux machine
  2. The client code is on a windows machine
  3. My internet speed is decent so I don't think that's the main problem
  4. I tried using socket.TCP_NODELAY but it had no effect

Just some extra bits of information that someone might find useful

Upvotes: 0

Views: 3488

Answers (1)

David Schwartz
David Schwartz

Reputation: 182763

You are sending a bunch of little bits of information one at a time instead of aggregating them together and sending them at once. This forces the implementation to be inefficient.

When the transport layer sees the first piece of data, it has no idea a second piece of data is coming, so it sends it immediately. But when it sees the second piece of data, it now has no idea how much data it's going to need to send (since it now sees it shouldn't have sent the first bit immediately), so it waits to see if you're going to send more by setting a 200 millisecond timer.

If you have a bunch of things you need to send at the same time, you need to combine into a single call into the underlying transport layer. Otherwise, you will force it to be inefficient because it never knows when it should send and when it should accumulate data.

Upvotes: 2

Related Questions