сделать клиент-сервер Java-приложением - PullRequest
9 голосов
/ 06 января 2011

Я пытаюсь сделать приложение Java клиент-серверным способом.Клиент представляет собой графический интерфейс в SWT, который отображает данные с сервера.Сервер подключен к базе данных.

Хорошо, извините за это, я уверен, это классический вопрос, но я не знаю с чего начать.поскольку они реализовали много волшебства с Proxy.newProxyInstance() для прозрачного вызова сервера Glassfish.

Я не хочу использовать сервер Glassfish.Я просто хочу что-то простое в простой Java.Но концепция прокси кажется довольно крутой.

У вас есть идеи или примеры таких вещей?Как мне написать серверную часть для обработки запросов клиентов?

Заранее спасибо

Fluminis

Ответы [ 4 ]

38 голосов
/ 06 января 2011

Я собираюсь объяснить TCP:
Основная концепция заключается в том, что вы должны запустить «Сервер» на машине. Этот сервер принимает клиентов, ожидающих соединения. Каждое соединение проходит через порт (вы знаете, я надеюсь ...).
Всегда используйте порты выше 1024, потому что порты ниже 1025 большую часть времени зарезервированы для стандартных протоколов (таких как HTTP (80), FTP (21), Telnet, ...)

Однако создание сервера в Java выполняется следующим образом:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on.

«Сокет» - это слово, которое вы, вероятно, ищете, если хотите провести исследование.
И чтобы подключить клиента к серверу, вы должны написать это:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port

Но сейчас еще нет связи. Сервер должен принять ожидающего клиента (как я заметил здесь выше):

Socket connectionToTheClient = server.accept();

Готово! Ваше соединение установлено! Общение - это как File-IO. Единственное, что вы должны иметь в виду, это то, что вы должны решить, когда вы хотите очистить буфер и действительно отправлять данные через сокет.
Использование PrintStream для написания текста очень удобно:

OutputStream out = yourSocketHere.getOutputStream();
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true
ps.println("Hello, Other side of the connection!");
// Now, you don't have to flush it, because of the auto-flush flag we turned on.

Хорошим (лучшим *) вариантом является BufferedReader для чтения текста:

InputStream in = yourSocketHere.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection.

Надеюсь, вы можете начать с сети с этой информацией!
PS: Конечно, весь сетевой код должен быть перехвачен для IOExceptions.

РЕДАКТИРОВАТЬ: Я забыл написать, почему это не всегда лучший вариант. BufferedReader использует буфер и читает как можно больше в буфер. Но иногда вы не хотите, чтобы BufferedReader крал байты после новой строки и помещал их в свой собственный буфер.
Краткий пример:

InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// The other side says hello:
String text = br.readLine();
// For whatever reason, you want to read one single byte from the stream,
// That single byte, just after the newline:
byte b = (byte) in.read();

Но у BufferedReader уже есть этот байт, который вы хотите прочитать, в своем буфере. Таким образом, вызов in.read() вернет байт, следующий за последним байтом в буфере считывателя.

Итак, в этой ситуации лучшее решение - использовать DataInputStream и управлять им по-своему, чтобы узнать, какой длины будет строка, и прочитать только это количество байтов и преобразовать их в строку. Или: Вы используете

DataInputStream.<del>readLine()</del>

Этот метод не использует буфер и читает побайтно и проверяет наличие новой строки. Так что этот метод не крадет байты из базового InputStream.


РЕДАКТИРОВАТЬ: вы можете разработать свой собственный протокол, в котором вы можете запросить вызов метода с помощью Java Reflexion. Например:

String className = ...;
String methodName = ...;
Class[] methodParamTypes = ...;
Object[] methodParams = ...;
Class cl = Class.forName(className);
Method me = cl.getDelcaredMethod(methodName, methodParamTypes);
Object returnValue = me.invoke(this, methodParams);

Получив свой объект, вы можете отправить его на другую сторону соединения с сериализацией: ObjectOuputStreams и ObjectInputStreams. С помощью этих двух классов вы можете писать и читать объекты через поток.

Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable)
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream());
oos.writeObject(oos);
oos.reset(); // (***)
// Don't close it! Otherwise the connection will be closed as well.

А на другой стороне соединения:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object object = ois.readObject(); // Read the object
// Don't close it!
// Then cast it to whatever you want.

(***): Проверьте мой вопрос для получения дополнительной информации о reset() и когда его использовать.

5 голосов
/ 06 января 2011

Glassfish может иметь больше огневой мощи, чем вам нужно, но я бы не отказался от использования существующей библиотеки.

Некоторые опции для розеток:

Если вы решите больше ориентироваться на веб-сервисы, чем на сокеты, Jetty - это путь для использования малого HTTP.

3 голосов
/ 06 января 2011

Если вы хотите написать простую программу типа клиент-сервер, вы можете следовать советам, данным в этом руководстве .

Если вы хотите сделать что-то более сложное, на простом Javaкак вы говорите, вам, возможно, придется взглянуть на RMI .

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

1 голос
/ 06 января 2011
  1. Определите сервисы, которые вы хотите предоставить (loadThing, editThing, makeThingBelch)
  2. выберите протокол связи / обмена сообщениями (http кажется простым.)
  3. внедрите сервисы, модульное тестированиечасто, чтобы убедиться, что они работают.
  4. СЕЙЧАС начинайте писать клиент, помня о том, что вам, возможно, придется добавлять новые сервисы или изменять существующие.

Одна вещь, которая приходит на ум, этоПочему вы хотите написать его в «простой Java», а не с использованием существующего сервера приложений?какая-нибудь вещь EJB3 для абстрагирования и управления связью, безопасностью, целостностью транзакций и т. д.?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...