LINUX.ORG.RU

Получение сообщений через сокеты

 ,


0

1

Есть сервер 1, который может принимать сообщения по сети от клиентов 2,3 и 4. В худшем случае все три клиента могут отправить сообщения одновременно. Во-первых, можно ли обойтись одним сокетом, открытым на 1 или нужна многопоточность? Во вторых, как определять размер данных которые нужно считать из сокета? И, наконец, как разграничивать сообщения между собой? Т.е если 2 записал в сокет сообщение длиной 2 байта, и сразу 3 записал сообщение длиной 10 байт. Как определить, что нужно считать сначала 2 байта, обработать, а затем считывать уже 10? Реализован ли необходимый функционал в фреймфорках вроде ZeroMQ? Сообщения предполагается передавать в формате JSON.

★★★

Используйте, пожалуйста, разметку. Очень сложно читать.

p.s. Не отвечайте только на это сообщение, чтобы после правки я его мог удалить и оно никому не мешало.

Deleted ()

От разных клиентов данные приходят в разных пакетах. Загугли простой эхо-сервер и сам все поймешь.

staseg ★★★★★ ()
Последнее исправление: staseg (всего исправлений: 1)
Ответ на: комментарий от staseg

Хотя-бы так.

Есть сервер 1, который может принимать сообщения по сети от клиентов 2,3 и 4. В худшем случае все три клиента могут отправить сообщения одновременно.

Во-первых, можно ли обойтись одним сокетом, открытым на 1 или нужна многопоточность?

Во вторых, как определять размер данных которые нужно считать из сокета?

И, наконец, как разграничивать сообщения между собой? Т.е если 2 записал в сокет сообщение длиной 2 байта, и сразу 3 записал сообщение длиной 10 байт. Как определить, что нужно считать сначала 2 байта, обработать, а затем считывать уже 10? Реализован ли необходимый функционал в фреймфорках вроде ZeroMQ? Сообщения предполагается передавать в формате JSON.

Deleted ()

Смутно догадываясь, что речь идёт о сокетах семейства IP, можно заметить, что половина вопросов абсолютно не имеет смысла для TCP, а половина - для UDP.

ABW ★★★★★ ()

Что ты все в кучу смешал? ZeroMQ - это сравнительно высокоуровневое middleware, если ты его юзать будешь, забудь вообще про открывание сокетов руками. А если хочешь как раз тупо сокетов, то выше тебе уже про пакеты сказали. А лучше всего - попробуй написать свой пинг-понг на чем-то императивном вроде сишечки.

anonymous ()
Ответ на: комментарий от ABW

Перефразируя ваш комментарий, получается что для tcp - остается вторая половина вопросов, а для udp - остается первая половина вопросов. Мне конечно выгоднее использовать tcp. Правильно я понял, что просто нужно слать на открытый сокет, а протокол сам разберется?

LIKAN ★★★ ()
Ответ на: комментарий от anonymous

Вот смотрю я на helloword-ный пример на языке Си на сайте zmq. И вижу создание сокета, bind на сервере, connect на клиенте, а потом до боли знакомые send, recv, правда с приставками zmq. Все выглядит почти так же, как и писать просто на C.

LIKAN ★★★ ()
Ответ на: комментарий от LIKAN

Для TCP - чтобы принимать соединения асинхронно, тебе нужна либо многопроцессность, либо многозадачность, либо моделирование многозадачности через select: в любом случае унаследованный сокет с открытым соединением - это фактически отдельный сокет, в который может писать только соединившийся, так что вопрос «как разделять» не имеет смысла. Вопрос «сколько читать» тоже не имеет смысла - это байтовый поток, читаешь либо сколько пришло, либо ждешь пока придёт сколько нужно.
В случае UDP сколько читать определяется размером пришедшего пакета, а разделение по обработчикам, если нужно, придётся делать вручную исходя из атрибутов пакета.

ABW ★★★★★ ()
Ответ на: комментарий от LIKAN

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

В случае tcp либо длину пакета кидай вначале, либо закрывай соединение как пакет отправил. В случае udp у тебя всегда одна датаграмма, сколько пришло все твое, и больше не будет. Разницы в подходах большие, смотря что именно нужно.

Многопоточность не обязательна, man poll/select. Гугли также simple tcp server, simple udp server.

arturpub ★★ ()
Ответ на: комментарий от LIKAN

void *subscriber = zmq_socket (context, ZMQ_SUB);*

это не то же самое, что взять и открыть обычный сокет. твой кпт.

anonymous ()

Есть сервер 1, который может принимать сообщения по сети от клиентов 2,3 и 4.

acceptor(Srv) ->
  {ok, Skt} = gen_tcp:accept(Srv),
  Starter = spawn_link(?MODULE, starter, []),
  gen_tcp:controlling_process(Skt, Starter),
  Starter ! {socket, Skt},
  acceptor(Srv).

В худшем случае все три клиента могут отправить сообщения одновременно

И? Каждому процессу свой сокет, не вижу проблемы.

Во-первых, можно ли обойтись одним сокетом, открытым на 1 или нужна многопоточность?

можно и с одним сокетом, можно и не с одним. Можно с многопоточностью, можно и без. Конкретизируй.

Во вторых, как определять размер данных которые нужно считать из сокета?

{ok, Srv} = gen_tcp:listen(3000, [
    binary,
    {packet, 4}, % <- this
    {active, true},
    {reuseaddr, true}]),

ZeroMQ?

эрлангисты смотрят на это поделие как на сам знаешь что.

Сообщения предполагается передавать в формате JSON.

Возьми лучше libei.a и напиши обёртку для bert-rpc. Отсутствие головной боли в дальнейшем гарантируется.

nanoolinux ★★★★ ()

можно начать с базового прочтения документации zeromq, в этом бы случае ни одно из вопросов не возникло.

Ответы:

Во-первых, можно ли обойтись одним сокетом, открытым на 1 или нужна многопоточность?

можно обойтись одним zeromq-socket-ом

многопоточность тут в любом случае ни при чем

Во вторых, как определять размер данных которые нужно считать из сокета?

никак, считывать размер пакета, если важно и пытаешься делать 0-copy, то во фрейме передавать размер, например

И, наконец, как разграничивать сообщения между собой?

zeromq делает это за тебя

Реализован ли необходимый функционал в фреймфорках вроде ZeroMQ?

все реализовано, читай документацию

Сообщения предполагается передавать в формате JSON.

это абсолютно не важно

qnikst ★★★★★ ()
Ответ на: комментарий от LIKAN

udp, ты с zeromq вообще пользовать не сможешь, не реализовано оно поверх udp. nanomsg тоже не реализовано (месяца 3 назад) было, хотя хотели запилить.

qnikst ★★★★★ ()

Лучше сначала разобраться с сетевым программированием. Например почитать Стивенса «UNIX. Разработка сетевых приложений».

four_str_sam ()
Ответ на: комментарий от LIKAN

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

four_str_sam ()

Реализован ли необходимый функционал в фреймфорках вроде ZeroMQ?

Да. Но книжку по сетям все равно прочти, тебе это очень и очень нужно.

g0t0 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.