Логин:   Пароль:






Новости
Рассылки
Форум
Поиск


Java
- Апплеты
- Вопрос-ответ
- Классы
- Примеры
- Руководства
- Статьи
- IDE
- Словарь терминов
- Скачать

Мобильная Java
- Игры
- Примеры
- Статьи
- WAP, WML и пр.

JavaScript
- Вопрос-ответ
- Примеры
- Статьи

Веб-мастеринг
- HTML
- CSS
- SSI

Разминка для ума
Проекты
Книги
Ссылки
Программы
Юмор :)




Rambler's Top100
Rambler's Top100

Java: СтатьиСоздаем клиент-сервер на сокетах

Создаем клиент-сервер на сокетах

Содержание

  • Что такое сокеты?
  • Создаем сервер
  • Создаем клиент
  • Замечания

    Что такое сокеты?

    Для начала давайте определим что такое сервер и клиент. Итак, сервер - это специальная программа, обычно запущенная на отдельном компьютере (хосте, от слова host(eng.) - хозяин), и выполняющая некий круг задач. Клиент, в свою очередь - программа, которая запрашивает сервер выполнить то или иное действие (задачу) и вернуть полученные данные клиенту. На хосте для работы сервера обычно выделяется порт (port). К этому порту и должен будет обращаться клиент. Клиент для связи с портом хоста, который соединен в свою очередь с нужным сервером (программой), создает сокет.

    В целом алгоритм работы системы клиент-сервер выглядит следующим образом:

    1. Сервер подключается к порту на хосте и ждет соединения с клиентом;
    2. Клиент создает сокет и пытается соединить его с портом на хосте;
    3. Если создание сокета прошло успешно, то сервер переходит в режим ожидания команд от клиента;
    4. Клиент формирует команду и передает ее серверу, переходит в режим ожидания ответа;
    5. Сервер принимает команду, выполнеят ее и пересылает ответ клиенту.
    6. и т.д.

    Теперь попробуем создать сервер и клиент.

    Создаем сервер

    Для создания сокетов и управления ими в Java есть специальные классы java.net.Socket и java.net.ServerSocket. Первый для клиента, второй для сервера. Так же нам будут необходимы два класса из пакета java.io.*: BufferedReader и PrintWriter для чтения/записи в сокет (думаю, что читатель уже знаком с этими классами).

    Для начала подключимся к порту хоста. Сделать это можно с помощью конструктора класса ServerSocket. Обратите внимание, что конструктор выбрасывает исключение типа IOException, т.е. нам понадобится блок try - catch:

    
     ServerSocket servers;
     try {
       servers = new ServerSocket(4444);
     } catch (IOException e) {
       System.out.println("Couldn't listen to port 4444");
       System.exit(-1);
     }
    

    После успешного подключения к порту сервер должен ждать подключения от клиента. Сделать это можно так:

    
     Socket fromclient;
     try {
       System.out.print("Waiting for a client...");
       fromclient= servers.accept();
       System.out.println("Client connected");
     } catch (IOException e) {
       System.out.println("Can't accept");
       System.exit(-1);
     }
    

    Рассмотрим этот блок подробнее. Метод servers.accept() позволяет серверу следить за портом, или иначе говоря ждать подключения клиента. Как только клиент подключается - сокет для клиента сразу же создается. В противном случае выбрасывается исключение IOException.

    Как только клиент подключился к серверу, сервер должен создать потоки ввода и вывода для связи с ним. Это можно сделать следующим образом:

    
     BufferedReader in;
     PrintWriter    out;
     in=new BufferedReader(new 
      InputStreamReader(fromclient.getInputStream())); 
     out = new PrintWriter(fromclient.getOutputStream(),true);
    

    И далее можно просто считывать данные из потока in и записывать данные в out.

    Исходный код сервера:

    
    import java.io.*;
    import java.net.*;
    
    public class Server {
    
      public static void main(String[] args) throws IOException {
        System.out.println("Welcome to Server side");
        BufferedReader in = null;
        PrintWriter    out= null;
    
        ServerSocket servers = null;
        Socket       fromclient = null;
    
        // create server socket
        try {
          servers = new ServerSocket(4444);
        } catch (IOException e) {
          System.out.println("Couldn't listen to port 4444");
          System.exit(-1);
        }
    
        try {
          System.out.print("Waiting for a client...");
          fromclient= servers.accept();
          System.out.println("Client connected");
        } catch (IOException e) {
          System.out.println("Can't accept");
          System.exit(-1);
        }
    
        in  = new BufferedReader(new 
         InputStreamReader(fromclient.getInputStream()));
        out = new PrintWriter(fromclient.getOutputStream(),true);
        String         input,output;
    
        System.out.println("Wait for messages");
        while ((input = in.readLine()) != null) {
         if (input.equalsIgnoreCase("exit")) break;
         out.println("S ::: "+input);
         System.out.println(input);
        }
        out.close();
        in.close();
        fromclient.close();
        servers.close();
      }
    }
    

    Создаем клиент

    Для создания клиента достаточно класса Socket и двух классов для ввода/вывода (см. Создаем сервер). Также необходимо знать имя компьютера (хоста), на котором запущен сервер и номер порта.

    Конструктор сокета имеет два параметра: имя хоста и номер порта. Опять таки, конструктор выбрасывает исключение типа IOException.

    
       Socket fromserver = null;
       fromserver = new Socket("localhost",4444);
    

    Далее аналогичным образом, как для сервера, создаем потоки ввода вывода. И можно записывать/считывать данные.

    Исходный код клиента:

    
    import java.io.*;
    import java.net.*;
    
    public class client {
      public static void main(String[] args) throws IOException {
    
        System.out.println("Welcome to Client side");
    
        Socket fromserver = null;
    
        if (args.length==0) {
          System.out.println("use: client hostname");
          System.exit(-1);
        }
    
        System.out.println("Connecting to... "+args[0]);
    
        fromserver = new Socket(args[0],4444);
        BufferedReader in  = new
         BufferedReader(new 
          InputStreamReader(fromserver.getInputStream()));
        PrintWriter    out = new 
         PrintWriter(fromserver.getOutputStream(),true);
        BufferedReader inu = new 
         BufferedReader(new InputStreamReader(System.in));
    
        String fuser,fserver;
    
        while ((fuser = inu.readLine())!=null) {
          out.println(fuser);
          fserver = in.readLine();
          System.out.println(fserver);
          if (fuser.equalsIgnoreCase("close")) break;
          if (fuser.equalsIgnoreCase("exit")) break;
        }
    
        out.close();
        in.close();
        inu.close();
        fromserver.close();
      }
    }
    
    

    Замечания

    Клиент-сервер организован на примере Echo server (Эхо сервер). Клиент получает обратно строку переданную серверу.


    Несколько замечаний по кодам:


    Обратите внимание на конструкцию методов main :
    
     public static void main(String[] args) throws IOException {}
    

    throws IOException позволит не использовать блоки try-catch для ловки исключения IOException в самом методе, что достаточно удобно.

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

           java client localhost
    

    Исходные коды


  • © Алексей Синельников, 2002 год.

    Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 11

    Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 19

    Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/books/show2b.php on line 19

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/books/show2b.php on line 30
    Узнай о чем ты на самом деле сейчас думаешь тут.


    [an error occurred while processing this directive]



    Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 91

    Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 93

    Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/news/worldnews.php on line 93

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/news/worldnews.php on line 95