Насколько быстрыми должны быть python сокетов? Почему мои работают очень медленно? - PullRequest
0 голосов
/ 05 мая 2020

Я написал небольшую программу, которая отправляет некоторые числа через сокеты. Я запускаю клиентскую программу на своем компьютере, а серверную программу - на виртуальной машине (размещенной на облачной платформе Google). Код, который я использую:

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())

Вывод из client.py показывает, что поездка туда и обратно отправки данных на сервер, а затем их получения и декодирования занимает около 0,2 секунды. Мне это кажется довольно высоким, разве сокеты не должны работать намного быстрее? Из этого сообщения кажется, что сокеты tcp в java могут совершить круговой обход за 2 микросекунд , что намного быстрее, чем мои 0,2 секунды. Я новичок ie, когда дело касается сокетов, поэтому я ни в чем не уверен. Если бы кто-нибудь мог дать мне некоторое представление или, возможно, сделать предложение о том, как включить сокеты для более быстрой работы (если это возможно, может быть, другой модуль или тип сокета?), Это было бы здорово.

Я начал работать с сокетами, потому что я хотел создать базовую c многопользовательскую игру из учебника, который мне дал (его сокеты, похоже, работают очень быстро), но после запуска этого кода количество времени, необходимое для данных до go между клиентам кажется, что это сделает игру неиграбельной или, по крайней мере, сильно медленной и совсем не увлекательной. Я кое-что видел об использовании UDP вместо TCP, но попробовав чей-то пример UDP, я обнаружил, что он работает так же медленно.

Примечание:

  1. Код сервера находится на linux машина
  2. Клиентский код находится на windows машине
  3. Моя inte rnet скорость приличная, поэтому я не думаю, что это основная проблема
  4. I пробовал использовать socket.TCP_NODELAY, но это не дало эффекта

Просто немного дополнительной информации, которая может оказаться полезной

1 Ответ

1 голос
/ 05 мая 2020

Вы отправляете кучу маленьких кусочков информации по одной, вместо того, чтобы объединять их вместе и отправлять их сразу. Это приводит к тому, что реализация становится неэффективной.

Когда транспортный уровень видит первую часть данных, он не подозревает, что идет вторая часть данных, поэтому отправляет ее немедленно. Но когда он видит вторую часть данных, он теперь не знает, сколько данных ему нужно отправить (поскольку теперь он видит, что не должен был отправлять первый бит немедленно), поэтому он ждет, чтобы увидеть, если вы собираюсь отправить больше, установив таймер на 200 миллисекунд.

Если у вас есть несколько вещей, которые вам нужно отправить одновременно, вам нужно объединить в один вызов на нижележащий транспортный уровень. В противном случае вы заставите его работать неэффективно, потому что он никогда не знает, когда следует отправлять и когда следует накапливать данные.

...