Android studio client server

Использование сокетов в Android

Создано большое количество приложений как для Android, так и для других ОС, которые взаимодействуют друг с другом с помощью установления соединенией по сети. К таким приложениям относятся, например, мессенджеры социальных сетей WhatsApp, Viber. Как правило, для установления соединения между такими приложениями используются сокеты.

Сокет (socket) — это интерфейс, позволяющий связывать между собой программы различных устройств, находящихся в одной сети. Сокеты бывают двух типов: клиентский (Socket) и серверный (ServerSocket). Главное различие между ними связано с тем, что сервер «открывает» определенный порт на устройстве, «слушает» его и обрабатывает поступающие запросы, а клиент должен подключиться к этому серверу, зная его IP-адрес и порт. В Android сокеты для передачи данных используют по умолчанию протокол TCP/IP, важной особенностью которого является гарантированная доставка пакетов с данными от одного устройства до другого.

Особенности использования сокетов

Что важно знать при использовании сокетов в Android ?

  • соединения сокетов отключаются при переходе устройства в спящий режим;
  • чтобы не «рвать» соединение при наступлении спящего режима в устройстве можно использовать сервис;
  • для использования интернет-сети необходимо Android-приложению предоставить нужные права в манифесте.

Для определения прав в манифесте необходимо в файл AndroidManifest.xml добавить следующую строку :

Теперь android-приложения будет иметь доступ к сети.

Далее в статье рассмотрим пример клиент-серверного сокетного соединения с передачей сообщения. Функции клиента будет выполнять android-приложение. Серверное java-приложение выполним в IDE Eclipse с использованием пакета concurrent. В конце страницы можно скачать оба приложения.

Клиентский android-сокет

Интерфейс andriod-приложения представлен на следующем скриншоте. Форма приложения включает поле ввода текстового сообщения и кнопки установления соединения сервером, передачи сообщения и закрытия соединения.

Клиентское приложение создадим из двух классов : класс взаимодействия с серверным сокетом Connection и класс стандартной активности MainActivity.

Класс Connection

Класс взаимодействия с сервером Connection получает при создании (через конструктор) параметры подключения : host и port. Методы Connection вызываются из активности и выполняют следующие функции :

Метод Описание
openConnection Метод открытия сокета/соединения. Если сокет открыт, то он сначала закрывается.
closeConnection Метод закрытия сокета
sendData Метод отправки сообщения из активности.
finalize Метод освобождения ресурсов

Листинг Connection

Класс активности MainActivity

В активности MainActivity определены параметры сервера : host, port. Помните, что IP-адрес сервера для Вашего android-примера не может быть localhost (127.0.0.1), иначе Вы будете пытаться связаться с сервером внутри Andriod-системы. Кнопки интерфейса связаны с методами обращения к классу Connection. Кнопки отправки сообщения mBtnSend и закрытия соединения mBtnClose с сервером блокируются при старте приложения. После установления соединения с сервером доступ к кнопкам открывается.

Листинг активности

Методы управления сокетным соединением

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

Серверное приложение

Серверное приложение включает 2 класса : Server и ConnectionWorker. Серверный класс Server будет выполнять обработку взаимодействия с клиентом с использованием ConnectionWorker в отдельном потоке. Конструктор ConnectionWorker в качестве параметра получает объект типа Socket для чтения сообщений клиента из потока сокета.

Листинг ConnectionWorker

ConnectionWorker получает входной поток inputStream из клиентского сокета и читает сообщение. Если сообщение отсутствует, т.е. количество прочитанных байт равно -1, то это значит, что соединение разорвано, то клиентский сокет закрывается. При закрытии клиентского соединения входной поток сокета также закрывается.

Серверный класс

Серверный класс Server создадим с использованием многопоточного пакета util.concurrent. На странице описания сетевого пакета java.net и серверного ServerSocket был приведен пример серверного модуля с использованием обычного потока Thread, при работе с которым необходимо решать задачу его остановки : cтарый метод Thread.stop объявлен Deprecated и предан строжайшей анафеме, а безопасная инструкция Thread.interrupt безопасна, к сожалению, потому, что ровным счетом ничего не делает (отправляет сообщение потоку : «Пожалуйста, остановись»). Услышит ли данный призыв поток остается под вопросом – все зависит от разаработчика.

Читайте также:  Android 2 views one activity

Чтобы иметь возможность остановить сервер «снаружи» в серверный класс Server включим 2 внутренних реализующих интерфейс Callable класса : CallableDelay и CallableServer. Класс CallableDelay будет функционировать определенное время, по истечении которого завершит свою работу и остановит 2-ой серверный поток взаимодействия с клиентами. В данном примере CallableDelay используется только для демонстрации остановки потока, организуемого пакетом util.concurrent.

Листинг CallableDelay

CallableDelay организует цикл с задержками. После завершения последнего цикла cycle поток завершает цикл, останавливает вторую задачу futureTask[1] и закрывает сокет. В консоль выводится соответствующее сообщение.

Листинг CallableServer

Конструктор CallableServer в качестве параметров получает значение открываемого порта для подключения клиентов. При старте (метод call) создается серверный сокет ServerSocket и поток переходит в режим ожидания соединения с клиентом. Остановить поток можно вызовом метода stopTask, либо завершением «задачи» типа FutureTask с данным потоком.

При подключении клиента метод serverSoket.accept возвращает сокет, который используется для создания объекта ConnectionWorker и его запуска в отдельном потоке. А сервер (поток) переходит к ожиданию следующего подключения.

В случае закрытия сокета (завершение внешней задачи FutureTask с данным потоком) будет вызвано исключение Exception, где выполняется проверка закрытия сокета; при положительном ответе основной цикл прерывается и поток завершает свою работу.

Листинг серверного класса Server

Cерверный класс Server создает два потоковых объекта (callable1, callable2), формирует из них две задачи futureTask и запускает задачи на выполнение методом execute исполнителя executor. После этого контролируется завершение выполнение обоих задач методом isTasksDone. При завершении выполнения обеих задач завершается также и цикл работы executor’а.

Два внутренних описанных выше класса (CallableDelay, CallableServer) не включены в листинг.

Источник

Android-er

For Android development, from beginner to beginner.

Saturday, February 8, 2014

Android Server/Client example — client side using Socket

It’s the client side implementation of our Server/Client example, the server side is listed in last post «server side using ServerSocket».

Android client side using Socket

Remark: uses-permission of «android.permission.INTERNET» is needed.

34 comments:

Works like a charm . Awesome

dear andr.oid eric, i created one application where socket programmin g is used, and that application not running on android version 4.0 and later.. i wnat ur help

thanks for your toturial guys

hmm. i try to connect android device to server but it didn’t well
if i try to eclipse emulator instead of android device, it works well
both of them, same situation. only emulator, android device difference
can you answer about my problem??
What can i check to solve this problem?

I am using hyperterminal to pass data to my android phone through wifi the data is being displayed on my phone at a random time and the data is scrambled and lot of extra garbage is also there, pls help!!

I can’t download the project file. The page doesn’t loading.

Hi.
Nice tutorial but i can not run it on my phone. How do i run it on my phone? Please help.

Thank you for posting this; it worked great on the emulator!

I’ll be migrating this app to a phone shortly. I’d also like to expand functionality to have indicators that display data sent from the server; do you have any posts on how I could achieve this? I’m new to Android and the site so will be rooting around in the coming days.

hello. sir
I am new to scripting language.. would you help me to learn this android scripting language by suggesting some useful links.

greet job. working well

Its really great, but in case when i don’t know about the server ip address then how can i connect with server as a client plzz tell me.

Читайте также:  Как можно восстановить удаленную резервную копию андроид

How can i user it for Instant messaging app in Android? And how to retrive port number from user while they initiate IM.

Hello. im just thinking if it is possible to divide the codes on connect button. by creating 2 buttons[connect,send].connect is just simply notify you if its connected, then send is to send a message to the server. can anyone help me?

I want to know which protocol is being used here. Is it telnet protocol ?

Awesome ..works very well. -)

Is it working over 4G connection? each device are not in same local network but have 4G connection. But I cannot send the socket. Pls how to solve it

I haven’t tried on mobile network. Somebody said the service provider will block the ports. So actually cannot, because of the mobile network service, not by the program.

ThanQ very Much For Best Script
It is Most Use full For Me But I have Some Problem is There any way to Read
Server Mobile Local Ip Address
i dont want enter Manually ip address in client side Mobile

hello The Creator,

I have no any good idea for your question.

Anyway, you can scan ip in your network, to find which devices can be reached. Scan Reachable IP to discover devices in network

Dear Sir,
Your code work fine,
But I want create once clientThread and reuse it to send different massages to server
because I need to send massage within one millisecond to the server

How can I use this with different network. It works only when both thw server an clients are in same networks.

hello ranjitha ak,

In my understanding, it depends on network setting, not related to the program.

Thanks for this tutorial, I am usually worried over the fact that people would take time to comment on ur work(post) but you find it very difficult to reply them especially when they need it.

Hi, Can anybody tell about UDP communication?

This program only partially works for me — pressing connect does show correct messages on the server device, but the client app only receives the input stream the one time into the buffer, then «inputStream.read(buffer)» receives no more data from the server and blocks the thread — i.e. never exits the while loop below.

while ((bytesRead = inputStream.read(buffer)) != -1) <
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString(«UTF-8»);
>

Appreciate your time for such a great tutorial. its Awesome, Loved it. simply the best 🙂

Hi,
Is it possible to do in UDP? I am working on this type of my student project.

It is better to close inputstream after read data:

InputStream inputStream = socket.getInputStream();

Great example I was struggling with it before I found this post.
I just can figure out how to send a String to the client?
Do I add the String to the ByteArrayOutputStream?

If you can show me I would appreciate it, Thanks.

Being new to this and would like to learn more. At present want to use android device with graphical buttons to send various commands via telnet?? Or other bidirectional protocol. Any help or links would be appreciated.

Please Share more Tutorials

Very Interesting Blog Post .Now a Days All the People in the world are Connected together by the Technology. Mainly makes human life Much Easier.
I Liiiike this tutorial

Very good, excellent post!

Very informative. Thanks for posting

Not working for multiple devices connection.

Источник

Простой клиент-сервер на Android (интернет-мессенджер)

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

Поехали. Многие мобильные приложения (и не только) используют архитектуру клиент-сервер. Общая схема, думаю, понятна.

Уделим внимание каждому элементу и отметим:

  • сервер — представляет собой некую программу, работающую на удаленном компьютере, и реализующую функционал «общения» с приложениями-клиентами (слушает запросы, распознает переданные параметры и значения, корректно отвечает на них);
  • клиент — в нашем случае, программа на мобильном устройстве, которая умеет формировать понятный серверу запрос и читать полученный ответ;
  • интерфейс взаимодействия — некий формат и способ передачи/получения запросов/ответов обеими сторонами.
Читайте также:  Необычные рингтоны для андроид

Неважно, как реализован любой из этих элементов, все они в любом случае присутствуют. Давайте реализуем примитивный сервер и Android клиент, работающий с ним. Как пример, будем использовать любой популярный мобильный интернет-мессенджер (Viber, ICQ), а приложение условно назовем «интернет-чат».

Схема взаимодействия следующая:

Клиент, установленный на устройстве А, посылает сообщение для клиента, установленного на устройстве Б. И наоборот. Сервер играет роль связующего звена между устройством А и Б… С, Д… и т.д. Также он играет роль «накопителя» сообщений, для их восстановления, на случай удаления на одном из клиентских устройств.

Для хранения сообщений используем SQL БД как на сервере, так и на устройствах-клиентах (в принципе, вся работа клиентов интернет-мессенджеров и сводится к постоянной синхронизации локальной и удаленной БД с сообщениями). Дополнительно, наш интернет-чат будет уметь стартовать вместе с запуском устройства и работать в фоне. Взаимодействие будет происходить путем HTTP запросов и JSON ответов.

Более логично, если синхронизация происходит через порт/сокет, это с одной стороны упрощает задачу (не нужно циклично слать HTTP запросы на проверку новых сообщений, достаточно проверять состояние прослушиваемого сокета), но с другой стороны, это усложняет создание серверной части приложения.

Делаем сервер

Для реализации «сервера», нам нужно зарегистрироваться на любом хостинге, который дает возможность работы с SQL и PHP.

Создаем пустую SQL БД, в ней создаем таблицу.

  1. author — автор сообщения;
  2. client — получатель сообщения;
  3. data — время и дата получения сообщения на сервере;
  4. text — сообщение.

В двух следующих файлах необходимо изменить переменные, содержащие данные для доступа к БД, на свои, полученные Вами при регистрации Вашего«сервера».

Структура запросов к api:

  • обязательный атрибут action — может быть равен select (сервер ответит списком записей из своей БД), insert (сервер добавить новую запись в свою БД), delete (сервер очистит свою БД)
  • если action=insert, нам нужно будет передать дополнительные параметры: author (кто написал сообщение), client (кому адресовано сообщение), text (сообщение)
  • action=select может содержать дополнительный параметр data, в этом случае ответ сервера содержит не все сообщения из БД, а только те, у которых время создания позднее переданного

Примеры:

  • chat.php?action=delete – удалит все записи на сервере
  • chat.php?action=insert&author=Jon&client=Smith&text=Hello — добавит на сервере новую запись: автор Jon, получатель Smith, содержание Hello
  • chat.php?action=select&data=151351333 — вернет все записи, полученные после переданного времени в long формате

Клиентская часть

Теперь структура Android приложения:

В фоне работает FoneService.java, который, в отдельном потоке, каждые 15 секунд делает запрос на сервер. Если ответ сервера содержит новые сообщения, FoneService.java записывает их в локальную БД и отправляет сообщение ChatActivity.java о необходимости обновить ListView, с сообщениями. ChatActivity.java (если она в этот момент открыта) получает сообщение и обновляет содержимое ListView из локальной БД.

Отправка нового сообщения из ChatActivity.java происходит сразу на сервер, минуя FoneService.java. При этом наше сообщение НЕ записывается в локальную БД! Там оно появится только после получения его назад в виде ответа сервера. Такую реализацию я использовал в связи с важным нюансом работы любого интернет-чата — обязательной группировкой сообщений по времени. Если не использовать группировку по времени, будет нарушена последовательность сообщений. Учитывая, что клиентские приложения просто физически не могут быть синхронизированы с точностью до миллисекунд, а возможно будут работать даже в разных часовых поясах, логичнее всего будет использовать время сервера. Так мы и делаем.

Создавая новое сообщение, мы передаем запросом на сервер: имя автора сообщения, имя получателя сообщения, текст сообщения. Получая эту запись назад, в виде ответа сервера, мы получаем то, что отправляли + четвертый параметр: время получения сообщения сервером.

Источник

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