15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Дополнительные сервисы на web серверах и сокеты в Java апплетах.

Автор: Павел Негробов.

    Иногда возникает необходимость организации какого-нибудь дополнительного сервиса на Web сервере. При этом дополнительный сервер цепляется на какой-нибудь нестандартный порт и прослушивает его. В страничку, которую пользователь получает обычным образом, встраивается апплет, реализующий клиента для этого нестандартного сервера. Такую схему можно реализовать с помощью стандартного механизма сокетов языка Java.
    Приведем пример реализации стандартного сервиса Time, выдающего клиенту текущее время. Обычно он реализуется на порту 37 и выдает 4 байтовое число, которое затем необходимо раскодировать, чтобы получить текущие дату и время. Мы же реализуем несколько иной механизм. Сервер будет посылать клиенту текущие дату и время в виде обычной строки, пригодной к распечатке без каких-либо перекодировок сразу после подключения и немедленно отключаться. Работать он будет на порту 8013.

Полный текст сервера:

// TimeServer.java
import java.net.*;
import java.io.*;

public class TimeServer extends Thread
{
private static final int kPortNumber = 8013;
private ServerSocket fServerSocket;

public TimeServer()
{
super("TServer");
try
{
  fServerSocket = new ServerSocket(kPortNumber);
  System.out.println("Time Server started ...");
}
catch (IOException e)
{
  System.err.println("Error: "+e);
  System.exit(1);
} // catch
} // TimeServer

public void run()
{
Socket theClientSocket;
while (true)
{
// Ожидание подключения клиента
if (fServerSocket == null) return;
try
{
theClientSocket = fServerSocket.accept();
// Прием соединения клиента
// Отправка клиенту сообщения

PrintWriter theWriter = new PrintWriter(new OutputStreamWriter(theClientSocket.getOutputStream()));
theWriter.println(new java.util.Date().toString());
theWriter.flush();

// разрыв соединения

theWriter.close();
theClientSocket.close();
} // try
catch (IOException e)
{
  System.err.println("Exception: " + e.getMessage());
  System.exit(1);
} // catch
} // while
} // run

public static void main(String[] args)

{

TimeServer theServer = new TimeServer();

theServer.start();

} // main

} // class

Приведем теперь текст апплета, обращающегося к этому серверу и HTML, запускающий его.

// GetTime.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.io.*;

public class GetTime extends Applet implements ActionListener
{
TextField text;

public void init()
{ // Initialize the applet.
//----------> Добавить панель управления
// Assign a BorderLayout manager with margins for this frame.

setLayout(new BorderLayout());

// -------------------
// Create two panels to contain two columns of components. Use our custom
// ColumnLayout layout manager for each. Add them on the west and
// center of the frame's border layout

Panel column1 = new Panel();
column1.setLayout(new ColumnLayout(5, 10, 2, ColumnLayout.LEFT));
add(column1, "West");

// -------------------
// Create a panel to contain the buttons at the bottom of the window
// Give it a FlowLayout layout manager, and add it along the south border

Panel buttonbox = new Panel();

buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 100, 10));
add(buttonbox, "South");

// Create pushbuttons and add them to the buttonbox

Button accept = new Button("GetTime");

buttonbox.add(accept);
accept.addActionListener(this);

// -------------------
// Create two 1-line text field and add to left column, with a labels

text = new TextField(30);
column1.add(text);
} // init

public void actionPerformed(ActionEvent ev)
{ // Button pressed, get Time
// Подключение к серверу

try
{
URL base=getDocumentBase();
Socket theSocket = new Socket(base.getHost(), 8013);
BufferedReader theReader = new BufferedReader(new
InputStreamReader(theSocket.getInputStream()));

// Ожидание поступления сообщения
// StringBuffer theStringBuffer = new StringBuffer(128);

String theLine;

int c;

while ((theLine = theReader.readLine()) != null)
{
// Вывод сообщения пользователю
// System.out.println("Сервер: " + theLine);

text.setText(theLine);
break;
} // while

// Разрыв соединения

theReader.close();
theSocket.close();
}
catch (IOException e)
{
text.setText("Error");
} // catch
} // actionPerformed
} // class

HTML для запуска этого апплета:

<html>
<head>
<title>Main page</title>
</head>

<body>
<applet code=GetTime.class width=225 height=140>
</applet>
</body>
</html>

Эта технология была проверена на IE 5.x и на Netscape Navigator 4.7. На обоих броузерах она работает.

Павел Негробов.

Email: pavel@imail.dc.ukrtel.net