Программирование - это просто
Advertisement
Главная arrow Уроки программирования arrow Java для чайников. arrow Java для чайников. Урок 33. Клиент серверное приложение.
01.03.2024 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
Java для чайников. Урок 33. Клиент серверное приложение. Печать E-mail
Автор megabax   
07.01.2020 г.
В этой статье я постараюсь максимально просто и понятно изложить основы программирования на языке Delphi

Java для чайников. Урок 33. Клиент серверное приложение.

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

import java.io.*;

import java.net.*;

import java.util.*;

 

 

public class StockQuoteServer {

    private static final int SERVER_PORT=1701; //порт, который будет прослушиваться сервером

    private static final int MAX_CLIENTS=50; //максимальное количество подключенных клиентов

    private static final File STOCK_QUOTES_FILE=new File("stockquotes.txt"); //файл с данными

    private ServerSocket listenSocket; //сокет

    private String[] stockInfo;

    private Date stockInfoTime;

    private long stockFileMode;

    private boolean keepRunning=true; //флаг, сброс которого приводит к завершению работы сервера

   

    //запуск приложения

    public static void main(String args[]) {

        StockQuoteServer server = new StockQuoteServer();

        server.serverQuotes(); 

    }

   

    //Конструктор загружает данные об акциях, после чего сервер

    //ожидает запросы от клиентов

    public StockQuoteServer()

    {

        if(!loadQuotes()) System.exit(1); //загружает данные, если ошибка - завершает работу

        try

        {

            listenSocket=new ServerSocket(SERVER_PORT, MAX_CLIENTS); //создать сокет

        } 

        catch(IOException except)

        {

            System.err.println("Unable to listen on port "+SERVER_PORT);

            System.exit(1);

        }

    }

   

    //загрузка данных из файла

    protected boolean loadQuotes()

    {

        String fileLine;

        StringBuffer inputBuffer=new StringBuffer();

        int numSocks=0;

        try

        {

            //создать поток для чтения данных из файла

            DataInputStream stockInput=new DataInputStream(new FileInputStream(STOCK_QUOTES_FILE));

           

            //считаем каждую строку

            while((fileLine=stockInput.readLine())!=null)

            {

                inputBuffer.append(fileLine.toUpperCase()+"\n"); //поместить строку в буфер

                numSocks++; //увеличить счетчик

            }

            stockInput.close();

           

            //сохранить время последней модификации

            stockFileMode=STOCK_QUOTES_FILE.lastModified();

           

        } catch(FileNotFoundException except)

        {

            System.err.println("Unable to find file: "+except);

            return false;

        } catch (IOException except)

        {

            System.err.println("I/O exception: "+except);

            return false;          

        }

       

        stockInfo=new String[numSocks]; //создадим массив строк для чтения инфы из файла

        String inputString=inputBuffer.toString();

       

        //указатели для создания подстрок

        int stringStart=0; //начало строки

        int stringEnd=0;  //конец строки

               

        for(int index=0; index<numSocks; index++)

        {

            stringEnd=inputString.indexOf("\n",stringStart);

           

            //если \n больше не встречается, то весь остаток inputString

            if(stringEnd==-1)

            {

                stockInfo[index]=inputString.substring(stringStart);

            }

            else

            {

                stockInfo[index]=inputString.substring(stringStart, stringEnd);

            }

           

            stringStart=stringEnd+1;  //передвинем указатель на следующую строку

        }

       

        stockInfoTime=new Date(); //сохраним время загрузки

        return true;       

    }

   

    //Этот метод ожидает обращение от клиента

    public void serverQuotes()

    {

        Socket clientSocket=null;

        try

        {

            while(keepRunning)

            {

                clientSocket=listenSocket.accept(); //присоединить нового клиента

               

                //Если файл данных изменен, загрузить данные повторно

                if(stockFileMode!=STOCK_QUOTES_FILE.lastModified())

                {

                    loadQuotes();

                }

               

                //Создать новый обработчик

                StockQuoteHandler newHandler = new StockQuoteHandler(clientSocket, stockInfo, stockInfoTime);            

                Thread newHandlerThread=new Thread(newHandler);

                newHandlerThread.start();

               

            }

            listenSocket.close();

        } catch(IOException e)

        {

            System.err.println("Failed I/O "+e);

        }

    }

   

    //метод для остановки сервера

    protected void stp()

    {

        if(keepRunning)

        {

            keepRunning=false;

        }      

    }

}

 

//Класс для обеспечения связи с отдельным клиентом

class StockQuoteHandler implements Runnable

{

    private Socket mySocket=null;

    private PrintStream clientSend=null;

    private DataInputStream clientReceive=null;

    private String[] stockInfo;

    private Date stockInfoTime;

   

    //конструктор

    public StockQuoteHandler(Socket newSocket, String[] info, Date time)

    {

        mySocket=newSocket;

        stockInfo=info;

        stockInfoTime=time;

    }

   

    //поток, релизующий обмен данными

    public void run()

    {

        String nextLine;

        String quoteID;

        String quoteResponse;

        try

        {

            clientSend=new PrintStream(mySocket.getOutputStream());

            clientReceive=new DataInputStream(mySocket.getInputStream());

            clientSend.println("+HELLO "+stockInfoTime);

            clientSend.flush();

           

            //получить строку от клиента и ответить

            while((nextLine=clientReceive.readLine())!=null)

            {

                nextLine=nextLine.toUpperCase();

               

                //команды выхода

                if(nextLine.indexOf("QUIT")==0) break;

               

                //команда STOCK

                else if(nextLine.indexOf("STOCK: ")==0)

                {                  

                    quoteID=nextLine.substring("STOCK: ".length());

                    quoteResponse=getQuote(quoteID);

                    clientSend.println(quoteResponse);

                    clientSend.flush();

                }

               

                //неизвестная команда

                else

                {

                    clientSend.println("-ERR UNKNOWN COMMAND");

                    clientSend.flush();

                }

            }

            clientSend.println("+BUY");

            clientSend.flush();

        } catch(IOException e)

        {

            System.err.println("Failed I/O "+e);

        } finally

        {

            //закроем потоки и сокет

            try

            {

                if(clientSend!=null) clientSend.close();

                if(clientReceive!=null) clientReceive.close();

                if(mySocket!=null) mySocket.close();

            } catch(IOException e)

            {

                System.err.println("Failed I/O "+e);

            }

        }

    }

   

    //Получить информацию по заданному идентификатору

    protected String getQuote(String quoteID)

    {

        for(int index=0; index<stockInfo.length; index++)

        {

            if(stockInfo[index].indexOf(quoteID)==0) return "+"+stockInfo[index];

        }

        return "-ERR UNKNOWN STOCK ID";

    }

}

 

Эта программа читает данные о котировках из текстового файла примерно такого вида:

IBM 123
Apple 333
General_Motors 12

 

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

Теперь создадим клиента:

import java.io.*;

import java.net.*;

 

 

public class StockQuoteClient {

 

    private static final int SERVER_PORT=1701; //сервер слушает этот порт

    private String serverName; //имя сервера

    private Socket quoteSocket=null; //сокет

    private DataInputStream quoteReceive; //поток очереди получения

    private PrintStream quoteSend; //поток очереди отправки

    private String[] stockIDs; //массив идентификаторов акций

    private String[] stockInfo; //массив возвращаемых значений

    private String currentAsOf=null; //Время обновления данных

   

    /*

    Запуск приложения: проверка параметров комнадной строки, создание нужных объектов и прочее

    */

    public static void main(String args[]) {

        if(args.length<2)

        {

            System.out.println("Usage: StockQuoteClient <server> <stock ids>");

            System.exit(1);

        }

        StockQuoteClient client=new StockQuoteClient(args);

        client.printQuotes(System.out);

        System.exit(0);

    }

   

    //конструктор класса

    public StockQuoteClient(String[] args)

    {

        String serverInfo;

        serverName=args[0]; //первый параметр - имя сервера

       

        //размер массива на 1 меньше, чем args

        stockIDs = new String[args.length-1];

        stockInfo = new String[args.length-1];

       

        //скопируем аргументы в массив stocksIDs

        for(int index=1; index<args.length; index++)

        {

            stockIDs[index-1]=args[index];

        }

       

        serverInfo=contactServer(); //связаться с сервером и возвратить сообщение приветсвия

       

        //распарсить строку с временем

        if(serverInfo!=null)

        {

            currentAsOf=serverInfo.substring(serverInfo.indexOf(" ")+1);

        }

        qetQuotes(); //считать информацию

        quitServer(); //закрыть соединение

    }

   

    //соединиться с ервером

    protected String contactServer()

    {

        String serverWelcome=null; //приглашение сервера

        try

        {

            quoteSocket =  new Socket(serverName, SERVER_PORT); //открыть сокет на сервер

            quoteReceive = new DataInputStream(quoteSocket.getInputStream());

            quoteSend=new PrintStream(quoteSocket.getOutputStream());

            serverWelcome=quoteReceive.readLine(); //считать приглашение сервера

        } catch (IOException except)

        {

            System.err.println("Unknown host "+serverName+": "+except);

        }

        return serverWelcome; //вернуть приглашение сервера

    }

   

    //считать информацию об акциях

    protected void qetQuotes()

    {

        String response; //ответ на запрос

       

        //если соединение в порядке

        if(connectOK())

        {

            try

            {

                //цикл по всем акциям

                for(int index=0; index<stockIDs.length; index++)

                {

                    if(stockIDs[index].indexOf("+")==0)

                    {

                        quoteSend.println(stockIDs[index].substring(1,stockIDs[index].length())); //послать запрос

                    }

                    else

                    {

                        quoteSend.println("STOCK: "+stockIDs[index]); //послать запрос

                    }

                    response=quoteReceive.readLine(); //получить ответ

                    stockInfo[index]=response.substring(response.indexOf(" ")+1); //распарсить полученные данные

                   

                }

            } catch (IOException except)

            {

                System.err.println("Failed I/O to"+serverName+": "+except);

            }

        }

    }

   

    //отключение от сервера

    protected String quitServer()

    {

        String serverBuy=null; //сообщение отключения

        try

        {

            //если соединение в порядке

            if(connectOK())

            {  

                quoteSend.println("QUIT");

                serverBuy=quoteReceive.readLine();

            }

           

            //если ссылки не равны NULL, то надо закрыть потоки и сокет

            if(quoteSend!=null)  quoteSend.close();

            if(quoteReceive!=null) quoteReceive.close();

            if(quoteSocket!=null) quoteSocket.close();

           

        } catch (IOException except)

        {

            System.err.println("Failed I/O to "+serverName+": "+except);

        }

       

        return serverBuy;

    }

   

   

    protected void printQuotes(PrintStream sendOutput)

    {

        //если уже было сообщение приветствия

        if(currentAsOf!=null)

        {

            sendOutput.print("INFORMATION ON REQUESTED QUOTES\nCurrent As Of: "+currentAsOf+"\n");

               

            //цикл по всем акциям

            for(int index=0 ;index < stockIDs.length; index++)

            {

                sendOutput.println(stockIDs[index]+":");

                if(stockInfo[index]!=null) sendOutput.println(" "+stockInfo[index]); else sendOutput.println();

            }

        }

    }

   

    //проверить, что с соединением все в порядке

    protected boolean connectOK()

    {

        return (quoteSend!=null && quoteReceive!=null && quoteSocket!=null);

    }

}

 

Итак, компилируем сервер, компилируем клиента. Запускаем сервер. Запускаем клиента, указывая в командной строке сначала хотс, а потом команды серверу, например, вот так:

"C:\Program Files (x86)\Java\jdk1.7.0_45\bin\java.exe" StockQuoteClient localhost IBM Apple +QUIT

 

В ответ вы увидите экран программы:

 

Java для чайников. Урок 33. Клиент серверное приложение.

 

 

(С) Шуравин Александр

 

 

Последнее обновление ( 07.01.2020 г. )
 
« След.   Пред. »
 
© 2024 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги