Java приложения передачи данных

Обмен данными по сети на основе сокетов в Java

Передача данных — одна из краеугольных задач информационных технологий. От неё зависит как работа компаний, так и повседневная жизнь обычных людей.

Для решения этой задачи Java предоставляет различные механизмы, среди которых особое место занимают сокеты.

Сокет (англ. socket — разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения (Википедия).

Ключевое отличие сокетов от других сетевых инструментов Java (таких как HttpRequest, SMTPTransport и др.) состоит в том, что:

  • Сокеты представляют собой достаточно низкоуровневый интерфейс.
    Это позволяет работать напрямую через протокол TCP/IP и тем самым обеспечивает универсальность.
  • Сокеты позволяют обеспечить обмен данными в режиме достаточно приближенном к реальному времени.
    При отсутствии задержек при обработке и передачи данных обмен происходит с очень высокой скоростью.

Недостаток сокетов, по сути является продолжением их достоинств. Универсальность и работа на низком уровне неизбежно порождает неудобство при работе с распространёнными протоколами (того же HTTP) . Поэтому для них лучше использовать высокоуровневые средства. Но, подобные протоколы, к сожалению, не покрывают весь спектр задач сетевого программирования. Поэтому программирование на сокетах по-прежнему остаётся актуальным.

Ниже мы рассмотрим примеры создания и работы серверных и клиентских сокетов на примере несложного клиент-серверного приложения.

Серверная часть

Существует два вида сокетов. Серверные и клиентские. В этой части мы рассмотрим серверные сокеты.

Читайте также:  Sort linked list in java

Серверные сокеты реализуются на основе класса ServerSocket. Они прослушивают определённый порт и по получении данных от клиента могут сформировать и передать ответ.

Ниже приведён пример создания серверного сокета для 5000 порта.

Источник

Java приложения передачи данных

Для передачи данных между двумя Activity используется объект Intent . Через его метод putExtra() можно добавить ключ и связанное с ним значение.

Например, передача из текущей activity в SecondActivity строки «Hello World» с ключом «hello»:

// создание объекта Intent для запуска SecondActivity Intent intent = new Intent(this, SecondActivity.class); // передача объекта с ключом "hello" и значением "Hello World" intent.putExtra("hello", "Hello World"); // запуск SecondActivity startActivity(intent);

Для передачи данных применяется метод putExtra() , который в качестве значения позволяет передать данные простейших типов — String, int, float, double, long, short, byte, char, массивы этих типов, либо объект интерфейса Serializable.

Чтобы получить отправленные данные при загрузке SecondActivity, можно воспользоваться методом get() , в который передается ключ объекта:

Bundle arguments = getIntent().getExtras(); String name = arguments.get("hello").toString(); // Hello World

В зависимости от типа отправляемых данных при их получении мы можем использовать ряд методов объекта Bundle. Все они в качестве параметра принимают ключ объекта. Основные из них:

  • get() : универсальный метод, который возвращает значение типа Object. Соответственно поле получения данное значение необходимо преобразовать к нужному типу
  • getString() : возвращает объект типа String
  • getInt() : возвращает значение типа int
  • getByte() : возвращает значение типа byte
  • getChar() : возвращает значение типа char
  • getShort() : возвращает значение типа short
  • getLong() : возвращает значение типа long
  • getFloat() : возвращает значение типа float
  • getDouble() : возвращает значение типа double
  • getBoolean() : возвращает значение типа boolean
  • getCharArray() : возвращает массив объектов char
  • getIntArray() : возвращает массив объектов int
  • getFloatArray() : возвращает массив объектов float
  • getSerializable() : возвращает объект интерфейса Serializable

Пусть у нас в проекте будет определено две activity: MainActivity и SecondActivity.

В коде SecondActivity определим получение данных:

package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class SecondActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setTextSize(26); textView.setPadding(16, 16, 16, 16); Bundle arguments = getIntent().getExtras(); if(arguments!=null)< String name = arguments.get("name").toString(); String company = arguments.getString("company"); int age = arguments.getInt("age"); textView.setText("Name: " + name + "\nCompany: " + company + "\nAge: " + age); >setContentView(textView); > >

В данном случае в SecondActivity получаем все данных из объекта Bundle и выводим их в текстовое поле TextView. Предполагается, что данной activity будут передаваться три элемента — две строки с ключами name и company и число с ключом price.

Теперь определим передачу в SecondActivity данных. Например, определим для MainActivity следующий интерфейс в файле activity_main.xml :

Здесь определены три текстовых поля для ввода данных и кнопка.

В классе MainActivity определим следующее содержимое:

package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); >public void onClick(View v) < EditText nameText = findViewById(R.id.name); EditText companyText = findViewById(R.id.company); EditText ageText = findViewById(R.id.age); String name = nameText.getText().toString(); String company = companyText.getText().toString(); int age = Integer.parseInt(ageText.getText().toString()); Intent intent = new Intent(this, SecondActivity.class); intent.putExtra("name", name); intent.putExtra("company", company); intent.putExtra("age", age); startActivity(intent); >>

В обработчике нажатия кнопки получаем введенные в текстовые поля EditText данные и передаем их в объект Intent с помощью метода putExtra() . Затем запускаем SecondActivity.

В итоге при нажатии на кнопку запустится SecondActivity, которая получит некоторые введенные в текстовые поля данные.

putExtra in Android и getString in Activity in Android Java

Передача сложных объектов

В примере выше передавались простые данные — числа, строки. Но также мы можем передавать более сложные данные. В этом случае используется механизм сериализации. Для этого нажмем на папку пакета, где находятся классы MainActivity и SecondActivity, правой кнопкой мыши и в контекстном меню выберем New -> Java Class :

Добавление класса Java в Android Studio

Назовем новый класс User — пусть он будет представлять пользователя.

Добавление класса Java в Android и передача сложных объектов в MainActivity

Пусть класс User имеет следующий код:

package com.example.viewapp; import java.io.Serializable; public class User implements Serializable < private String name; private String company; private int age; public User(String name, String company, int age)< this.name = name; this.company = company; this.age = age; >public String getName() < return name; >public void setName(String name) < this.name = name; >public String getCompany() < return company; >public void setCompany(String company) < this.company = company; >public int getAge() < return age; >public void setAge(int age) < this.age = age; >>

Стоит отметить, что данный класс реализует интерфейс Serializable . Теперь изменим код MainActivity:

package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); >public void onClick(View v) < EditText nameText = findViewById(R.id.name); EditText companyText = findViewById(R.id.company); EditText ageText = findViewById(R.id.age); String name = nameText.getText().toString(); String company = companyText.getText().toString(); int age = Integer.parseInt(ageText.getText().toString()); User user = new User(name, company, age); Intent intent = new Intent(this, SecondActivity.class); intent.putExtra(User.class.getSimpleName(), user); startActivity(intent); >>

Теперь вместо трех разрозненных данных передается один объект User. В качестве ключа используется результат метода User.class.getSimpleName() , который по сути возвращает название класса.

И изменим класс SecondActivity:

package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class SecondActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); //setContentView(R.layout.activity_second); TextView textView = new TextView(this); textView.setTextSize(26); textView.setPadding(16, 16, 16, 16); Bundle arguments = getIntent().getExtras(); User user; if(arguments!=null)< user = (User) arguments.getSerializable(User.class.getSimpleName()); textView.setText("Name: " + user.getName() + "\nCompany: " + user.getCompany() + "\nAge: " + String.valueOf(user.getAge())); >setContentView(textView); > >

Для получения данных применяется метод getSerializable() , поскольку класс User реализует интерфейс Serializable. Таким образом, мы можем передать один единственый объект вместо набора разрозненных данных.

Источник

Java приложения передачи данных

В библиотеке классов Java есть очень удобное средство, с помощью которых можно организовать взаимодействие между приложениями Java и аплетами, работающими как на одном и том же, так и на разных узлах сети TCP/IP. Это средство, родившееся в мире операционной системы UNIX, — так называемые сокеты (sockets).

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

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

С адресом узла IP вы уже сталкивались. Номер порта служит для идентификации приложения. Заметим, что существуют так называемые «хорошо известные» (well known) номера портов, зарезервированные для различных приложений. Например, порт с номером 80 зарезервирован для использования серверами Web при обмене данными через протокол HTTP.

Что же касается типов сокетов, то их два — потоковые и датаграммные.

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

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

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

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

Причина отстутствия гарантии доставки данных при использовании датаграммных сокетов заключается в использовании такими сокетами протокола UDP, который, в свою очередь, основан на протоколе с негарантированной доставкой IP. Потоковые сокеты работают через протокол гарантированной доставки TCP.

Источник

Оцените статью