2016-05-18 12 views
0

Как переносить большие данные без разделения. Я использую tcp socket. Это для игры. Я не могу использовать udp, и в массиве может быть 1200 значений. Я посылаю массив в формате json. Но сервер получает его, как разделенный.Как передать большие данные через сокет tcp

Также есть возможность отправить HTTP-запрос, например, tcp? Мне нужен ответ в порядке. Также это должно быть быстрее.

Спасибо,

+1

Чем меньше пакет, тем лучше вероятность его разложения, но вы никогда не сможете контролировать, происходит ли расщепление, если вы не владеете сеть до конца. – xaxxon

+0

Не используйте JSON. Если все эти 1200 значений не более одного байта, вы можете использовать двоичный массив с фиксированными позициями переменных. Это почти наверняка будет меньше, чем ваш текущий MTU. И если вам нужно все принимать в порядок, подумайте о долговременном соединении, а не о многих маленьких. – DaSourcerer

ответ

1

Вы не имеете много контроля над расщеплением пакетов/дейтаграммами. Сеть решает об этом.

В случае IP у вас есть флаг DF (не фрагмент), но я сомневаюсь, что здесь будет много помощи. Если вы обмениваетесь данными по Ethernet, то массив 1200 элементов может не вписаться в кадр Ethernet (размер полезной нагрузки зависит от MTU 1500 октетов).

Почему ваше приложение зависит от того, что все данные должны поступать в одном устройстве, а не в одном соединении (состоящем из нескольких блоков)?

+0

Его игровое соединение с 1200 значениями. Его пошаговая игра. Его связь с сервером. Есть ли другой вариант, который я мог бы использовать? Пробовал HTTP-запрос и его медленный. Также мне нужны сообщения в порядке, это не тот случай, когда я использую http. – swaraj

+0

Итак, какова ваша ** настоящая ** проблема? Даже 1200 * 1200 значений не проблема в сети связи. Почему вы не любите раскалывать и так хотите ретранслировать на ** одиночные ** датаграммы/пакеты? Почему ваш сервер не ожидает завершения всего соединения (= последовательность пакетов/датаграмм) до обработки этих данных? –

+0

при отправке большого количества данных, занимает некоторое время. Он разделяет данные на 4. Таким образом, он занимает около 5-6 секунд в медленном сетевом соединении. Я мог бы сократить время. Только 5 секунд предоставляется изменение хода от одного игрока к другому. – swaraj

1

Вы не можете.

  • HTTP может ломоть это
  • TCP сегмент это
  • IP будет пакетировать это
  • маршрутизаторы фрагментировать его ...
  • и TCP будет собрать все это на другом конце.

Здесь нет проблем.

+0

Его игровое соединение с 1200 значениями. Его пошаговая игра. Его связь с сервером. Можете ли вы предложить лучший вариант для этого? – swaraj

+0

Лучший вариант для чего? Вы должны задать правильный вопрос, если хотите получить ответ. Насколько велика, например, «ценность»? Один байт? Один гигабайт? – EJP

+0

«HTTP может его разбить» - можете ли вы указать, где находится спецификация? «Здесь не проблема, чтобы решить проблему». Проблемой решения является латентность. – xaxxon

1

Рассмотрите идею о том, что проблема может быть другой, где или что вы можете отправлять слишком много ненужных данных. В примере с PHP есть функция isset(). Если вы создаете пошаговую игру в Интернете, вам не нужно (нужно, чтобы отправить все 1 200 переменных взад и вперед каждый раз. Просто отправьте то, что изменилось, и когда другой игрок получает эти данные, только переменные имеют значение установить.

+0

На самом деле его пошаговая игра с 1200 ставками. Поэтому он должен быть сохранен в базе данных. – swaraj

0

как я могу передавать большие объемы данных без разделения.

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

  1. Держать одно TCP-соединение открытым. (HTTP традиционно открывает отдельное TCP-соединение для каждого запроса, но для низкой задержки вы не можете этого сделать. Вместо этого вам нужно открыть одно TCP-соединение, оставить его открытым и продолжить отправку/получение данных на нем, поскольку по мере необходимости).
  2. Уменьшите объем данных, необходимых для отправки. (т. е. есть ли какие-то вещи, которые вы отправляете, которые уже получает программа приема? Если да, не отправляйте их)
  3. Уменьшите количество байтов, которое необходимо отправить.(Самый простой способ сделать это - zlib -создавать свои данные сообщений перед отправкой, а при получении принимающей программы распаковать сообщение после его получения. Это может привести к уменьшению размера на 50-90%, в зависимости от содержимое ваших данных)
  4. Отключите Nagle's algorithm на вашем TCP-сокете. Это уменьшит задержку на 200 мс и обескураживает стек TCP от ненужных игр с вашими данными.
  5. Отправляйте каждый пакет данных с помощью одного вызова send() (если это означает, что нужно вручную копировать все элементы данных в отдельный буфер памяти перед вызовом send(), то пусть будет так).

Обратите внимание, что даже после выполнения всех вышеперечисленных действий уровень TCP по-прежнему иногда распространяет ваши сообщения на несколько пакетов и т. Д. - это именно так, как работает TCP. И даже если ваш локальный стек TCP никогда не делал этого, TCP-стек получающего компьютера по-прежнему иногда объединял данные из последовательных TCP-пакетов вместе внутри своего буфера приема. Таким образом, принимающая программа всегда собирается «получать ее, как разделенную», иногда, потому что TCP является потоковым протоколом и не поддерживает границы сообщений. (Если вам нужны границы сообщений, вам нужно будет сделать свой собственный кадрирование - самый простой способ - это, как правило, отправлять целое число байтов фиксированного размера (например, 1, 2 или 4 байта) перед каждым сообщением, поэтому получатель знает, сколько байтов ему нужно прочитать, прежде чем у него будет полное сообщение для разбора)

+0

Вы 17 лет устарели. HTTP 1.1 «традиционно» использует «Connection: keepalive». – EJP