Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Программа простого TCP/IP сервера




(SampleServer.java)

import java.io.*;import java.net.*; class SampleServer extends Thread{ Socket s; int num; public static void main(String args[]) { try { int i = 0; // счётчик подключений // привинтить сокет на локалхост, порт 3128 ServerSocket server = new ServerSocket(3128, 0, InetAddress.getByName("localhost")); System.out.println("server is started"); // слушаем порт while(true) { // ждём нового подключения, после чего запускаем обработку клиента // в новый вычислительный поток и увеличиваем счётчик на единичку new SampleServer(i, server.accept()); i++; } } catch(Exception e) {System.out.println("init error: "+e);} // вывод исключений } public SampleServer(int num, Socket s) { // копируем данные this.num = num; this.s = s; // и запускаем новый вычислительный поток (см. ф-ю run()) setDaemon(true); setPriority(NORM_PRIORITY); start(); } public void run() { try { // из сокета клиента берём поток входящих данных InputStream is = s.getInputStream(); // и оттуда же - поток данных от сервера к клиенту OutputStream os = s.getOutputStream(); // буффер данных в 64 килобайта byte buf[] = new byte[64*1024]; // читаем 64кб от клиента, результат - кол-во реально принятых данных int r = is.read(buf); // создаём строку, содержащую полученную от клиента информацию String data = new String(buf, 0, r); // добавляем данные об адресе сокета: data = ""+num+": "+""+data; // выводим данные: os.write(data.getBytes()); // завершаем соединение s.close(); } catch(Exception e) {System.out.println("init error: "+e);} // вывод исключений }}

После компиляции, получаем файлы SampleServer.class и SampleClient.class (все программы здесь и далее откомпилированы с помощью JDK v1.4) и запускаем вначале сервер:

java SampleServer

а потом, дождавшись надписи "server is started", и любое количество клиентов:

java SampleClient test1java SampleClient test2...java SampleClient testN

Если во время запуска программы-сервера, вместо строки "server is started" выдало строку типа

init error: java.net.BindException: Address already in use: JVM_Bind

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

Заметки

Отметим немаловажную особенность сокета сервера: он может принимать подключения сразу от нескольких клиентов одновременно. Теоретически, количество одновременных подключений неограниченно, но практически всё упирается в мощность компьютеров. Кстати, эта проблема конечной мощности компьютеров используется в DOS атаках на серверы: их просто закидывают таким количеством подключений, что компьютеры не справляются с нагрузкой и "падают".

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

Стоит упомянуть, что абстракцию Socket - ServerSocket и работу с потоками данных используют C/C++, Perl, Python, многие другие языки программирования и API операционных систем, так что многое из сказанного подходит к применению не только для платформы Java.


Для работы с сокетами понадобиться пакеты

java.net

java.io

 

Основные этапы создания приложения:

· Сервер (Tim) - Создаём новый сокет, ожидающий запросы от клиента на 4444 порту.

· Клиент (Chris) - Создаём новый сокет, который будет конектиться к Tim на 4444 порт.

· Начинаем передачу данных между клиентом и сокетом.

Socket serverSocket = null;

serverSocket = new Socket(4444); //Notice no user to connect to this time.

serverSocket.accept(); //Accept a client.

Теперь приступим к передаче данных между Клиентом и Сервером.

Задача серверного сокета заключается в том, чтобы за один сеанс связи принять данные от клиента и сразу же передать клиенту ответ. Чтобы произвести такую операцию необходимо объявить потоки PrintWriter для вывода и поток BufferedReader для ввода. Причём объявить потоки необходимо как на сервере, так и на клиенте:

PrintWriter out = null;

BufferedReader in = null;

Socket clientSocket = null;

 

clientSocket = new Socket("Tim", 4444);

//get the socket's ouput

out=new PrintWriter(clientSocket.getOutputStream(), true);

//get the socket's input

in=new BufferedReader(new inputStreamReader(clientSocket.getInputStream()));

Теперь PrintWriter out будет выходным потоком, при записи в который, данные будут направляться в сокет. Если теперь выполнить out.println("Hello"), то строка hello будет отправлена серверу.

Чтобы приём информации на сервере шёл непрерывно:

PrintWriter out = null;

BufferedReader in = null;

Socket clientSocket = null;

String fromServer;

 

clientSocket = new Socket("Tim", 4444);

out = new PrintWriter(clientSocket.getOutputStream(), true);

in = new BufferedReader(new inputStreamReader(clientSocket.getInputStream()));

 

// Цикл до тех пор, пока есть поступающие сообщения

while ((fromServer = in.readLine())!= null) {

//Отображаем полученное сообщение

System.out.println("Server: " + fromServer);

}

 

out.close();

in.close();

clientSocket.close();

 






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных