Reputation: 170
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:
socket.TCP_NODELAY
but it had no effectJust some extra bits of information that someone might find useful
Upvotes: 0
Views: 3488
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