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

Автор: content Понедельник, Апрель 9th, 2012 Нет комментариев

Рубрика: Язык 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

Источник: http://www.javaportal.ru/java/articles/ClientServer.html
Автор: Алексей Синельников, 2002

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

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты