Отправка сообщения с TCP-сервера в erlang

Я только начал работать с Erlang. Я хочу создать TCP-сервер в Erlang. Мой TCP-клиент работает на Android и подключается к серверу. Я взял реализацию TCP-сервера с сайта https://github.com/kevinlynx/erlang-tcpserver

Я могу запустить сервер, подключить к нему клиента и отправлять сообщения с клиента на сервер. Кроме того, логика сервера заключается в том, что всякий раз, когда он получает сообщения от клиента, он отправляет обратно то же самое сообщение клиенту.

Все это прекрасно работает, моя единственная проблема заключается в том, как отправить сообщение клиенту из оболочки erlang (без необходимости ждать сообщения от клиента). Функция gen_tcp:send() требует в качестве входных данных дескриптор сокета, всякий раз, когда клиент отправляет сообщение, происходит обратный вызов, и он имеет дескриптор сокета, поэтому его можно использовать для отправки сообщения обратно клиенту, а как по другому?


person Archit Sinha    schedule 01.06.2017    source источник


Ответы (2)


На стороне сервера вы должны где-то принимать соединение:

 {ok, Sock} = gen_tcp:accept(LSock)

И я полагаю, вы могли бы отправить сообщение в этот сокет:

gen_tcp:send(Sock, YourPacket)

Если вы не принимаете соединения, то это не сервер.

Обновление для ответа на комментарий

Одним из способов является совместное использование сокета слушателя (в примере LSock). Вы можете сохранить его в доступном ETS и вызвать акцептор из оболочки, несмотря на то, что он не был владельцем приемника.

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

person Asier Azkuenaga    schedule 01.06.2017
comment
Да, соединение принимается на сервере со строкой {ok, Sock} = gen_tcp:accept(LSock), (в строке 39 в tserver.erl). Но мой вопрос в том, как мне получить этот Sock в оболочке при запуске команда? Я запускаю сервер с помощью test:start(). (test.erl — это файл, а start() — это функция в нем, которая запускает сервер). Итак, когда я запускаю это в оболочке, как мне получить Sock, упомянутый выше? Как только я получаю Sock, я понимаю, что могу использовать gen_tcp:send() для отправки сообщения. Я что-то упустил здесь? - person Archit Sinha; 01.06.2017

Я только начал работать с Erlang. Я хочу создать TCP-сервер в Erlang.

Я думаю, проблема в том, что вы используете программное обеспечение, которое устанавливает канал связи между клиентом и сервером:

(client) ================== (server)

Теперь у вас есть третья сущность:

(client) ================== (server)

          (erlang shell)

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

Оболочка erlang может стать вторым клиентом сервера:

(client) ================== (server)

(erlang shell) ============ (server)

но это не помогает оболочке erlang напрямую общаться с клиентом. Оболочка erlang может отправить некоторую информацию на сервер, и сервер может сохранить эту информацию в состоянии, а затем сервер может передать состояние клиенту в следующий раз, когда клиент сделает запрос.

Если бы у оболочки erlang был PID клиента, оболочка erlang всегда могла бы сделать:

Pid ! "hello client"

и если клиент ждал в операторе приема, то клиент мог извлечь это сообщение из своего почтового ящика. Как выглядит ваш клиент?

person 7stud    schedule 03.06.2017