Соединение сокета сервера с двумя разными приложениями, Java

#java #blocking #serversocket

#java #блокировка #serversocket

Вопрос:

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

Приложение 1<——> Сервер<——> Приложение 2

Сервер извлекает var1 из app2, записывает его в app1, затем считывает var2 из app1 и записывает его в app2. Вот так :

while(true){
var1 = app2stream.readInt();
app1stream.writeInt(var1);
var2 = app1stream.readDouble();
app2stream.writeDouble(var2);
}

Моя проблема в том, что в какой-то момент у меня есть этот код на моем сервере :

app1.accept();
app2.accept();

Это означает, что независимо ни от чего, и учитывая тот факт, что сервер всегда запущен, app1 — это тот, который должен подключиться первым, поскольку app1.accept() — это метод блокировки.

Есть ли какой-либо способ обойти это? Было бы здорово разрешить двум приложениям подключаться к серверу независимо от того, кто «пришел» первым, а затем дождаться, пока сервер выполнит приведенный выше код. Могу ли я использовать потоки только для части accept(), а затем передавать потоки в другой поток? Я немного читал о каналах, но немного запутался, любые примеры были бы великолепны.

Комментарии:

1. Рассматривали ли вы реализацию JMS? Похоже, это именно то, для чего он предназначен.

Ответ №1:

Используйте NIO

Это позволяет вам создавать неблокирующие сокеты (включая accept), используя Selector класс.

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

Комментарии:

1. Я читаю статью, на которую вы ссылались, спасибо, я вернусь, если у меня возникнут какие-либо вопросы!

2. мне было интересно, возможно ли использовать каналы NIO и класс selector для сервера, но при этом использовать простой DataOutput / InputStream в двух других приложениях (которые являются клиентами), чтобы мне не пришлось менять слишком много кода?

3. Ну, конечно. Если уж на то пошло, они могли бы быть написаны на perl 🙂 Вы просто используете сокеты TCP.

Ответ №2:

Есть только один вызов accept и один серверный сокет. Вы можете определить, какое приложение подключилось, как только они подключатся. Если вы не можете получить это из сведений о подключении, попросите их отправить authcode (в любом случае, вероятно, это хорошая идея), который вы можете сопоставить с вашим приложением.

Ответ №3:

Вероятно, вам следует относиться к ним обоим одинаково, если они не говорят иначе.

Например, когда каждый сокет подключается, отправьте запрос «какой клиент?» Сообщение.

Затем проверьте, отвечает ли клиент на 1 или 2.

Если оба отвечают 1 или чем-то еще, просто отключите оба.

Ответ №4:

Я думаю, что «стандартный» способ сделать это — заставить сервер прослушивать порт, и когда приходит сообщение, немедленно запустить новый поток для его обработки, затем вернуться к прослушиванию другого сообщения. Затем, как говорит Glowcoder, сделайте все соединения в одном цикле и заставьте его определить, что есть что, после подключения.

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