Python: Почему TCP-клиент Python так медленно получает данные на разных компьютерах? - PullRequest
0 голосов
/ 29 мая 2019

У меня есть два скрипта Python, один TCP-сервер отправляет данные (со скоростью 1/256 раз в секунду) и TCP-клиент получает данные. В клиентском скрипте я печатаю длину полученных данных. Я отправил строку "5.8" с сервера (таким образом, данные длины 3).

Когда клиент и сервер находятся на одном компьютере: Длина полученных данных всегда равна 3. Когда клиент и сервер находятся на разных компьютерах в одной локальной сети: Длина данных отличается, но составляет около 39 (в 13 раз больше отправленных данных).

Есть ли возможное объяснение этому расхождению?

Я думаю, что сеть, добавляющая такую ​​большую задержку, маловероятна, потому что командная строка «ping» печатает с задержкой не более 2 мс с наибольшим объемом данных.

ВАЖНО: я использую Python 2.7.

import socket

def server():
    host = 'localhost' # replace with IP address in case client is on another machine
    port = 5051

    s = socket.socket()
    s.bind((host, port))
    s.listen(1)
    client_socket, adress = s.accept()

    while True:
        client_socket.send('a'.encode())
    client_socket.close()

if __name__ == '__main__':
    server()
import socket, random, time

def client():
    host = 'localhost' # replace with IP address in case client is on another machine
    port = 5051

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s_err = s.connect_ex((host, port))
    print(s_err)

    while True:
        data = s.recv(2048)
        print(len(data)) # returns different values depending on client location
    s.close()

if __name__ == '__main__':
    client()

Ответы [ 3 ]

0 голосов
/ 30 мая 2019

Я бы предположил, что стек TCP / IP сервера только что объединил небольшие пакеты для лучшей пропускной способности сети.Чтобы отправить только 3 данных полезной нагрузки, вам потребуются большие издержки: инкапсуляция TCP + инкапсуляция IP.Многие стеки TCP / IP используют это.

В любом случае, вам не следует ни волноваться об этом, ни удивляться, происходит ли это или нет: TCP является потоковым протоколом, и единственная гарантия состоит в том, что все байты отправляются с одной стороны.прибудет в том же порядке на другую сторону.Любое оборудование (отправитель-получатель или любое другое устройство в сети) может объединять фрагменты пакетов.

0 голосов
/ 23 июня 2019

Это то, что мне помогло: я изменил размер буфера recv () на количество байтов, которое я хочу получить, поэтому в этом случае

data = s.recv(3)

вместо

data = s.recv(2048)

Находясь на локальной машине, что-то автоматически решило, что данные могут быть отправлены в наименьших пакетах, хотя это было не так при использовании локальной сети.Поэтому я увеличил размер отправляемых данных.

Это, конечно, потенциально может привести к проблемам с задержкой.Так что в другом месте мне нужно убедиться, что оставшиеся данные регулярно очищаются с большим размером буфера, или закрыть соединение, если не нужно.Не уверен насчет последнего, так как я все еще начинающий.

0 голосов
/ 29 мая 2019

Есть ли возможное объяснение этому расхождению?

В TCP отсутствует концепция сообщения.Данные, отправленные с использованием нескольких вызовов send, могут быть получены одним вызовом recv и наоборот.

TCP - это поток, в котором вам нужно самостоятельно разграничить сообщения, чтобы читатель мог определить границы сообщений.Наиболее распространенные способы:

  1. Префикс сообщений с фиксированной длиной сообщения.
  2. Чтение, пока не встретится разделитель сообщений, например, \n.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...