Что такое сокет java
Термин «сетевое программирование» относится к написанию программ, которые выполняются на нескольких устройствах (компьютерах), в которых все устройства подключены друг к другу с помощью сети.
Содержание
Протоколы TCP и UDP
- TCP - TCP - это протокол управления передачей, который обеспечивает надежную связь между двумя приложениями. В Java TCP обычно используется через Интернет-протокол, который называется TCP/IP.
- UDP - UDP - это протокол пользовательских дейтаграмм, протокол без установления соединения, который позволяет передавать пакеты данных между приложениями.
Данная глава надлежащим образом раскрывает следующие две темы:
- Программирование сокетов - это наиболее широко используемая концепция в сетевой конфигурации, о которой было подробно изложено.
- Обработка URL (унифицированный указатель ресурсов) - этот процесс будет рассмотрен отдельно. Перейдите по ссылке, чтобы узнать об обработке URL на языке Java.
Программирование сокетов
В Java сокеты обеспечивают механизм связи между двумя компьютерами, использующими TCP. Клиентская программа создает сокет на своем конце связи и пытается подключить этот сокет к серверу.
Когда соединение установлено, сервер создает объект сокета на своем конце связи. Клиент и сервер теперь могут общаться, записывая и считывая данные с сокета.
При установлении соединения TCP между двумя компьютерами с использованием сокетов, выполняются следующие этапы:
- Сервер создает экземпляр объекта ServerSocket, определяющий, по какому номеру порта должна происходить связь.
- Сервер вызывает метод accept() класса ServerSocket. Этот метод ожидает, пока клиент не подключится к серверу по указанному порту.
- По завершению ожидания сервера клиент создает экземпляр объекта сокета, указывая имя сервера и номер порта подключения.
- Конструктор класса Socket осуществляет попытку подключить клиента к указанному серверу и номеру порта. Если связь установлена, у клиента теперь есть объект Socket, способный связываться с сервером.
- На стороне сервера метод accept() возвращает ссылку к новому сокету на сервере, который подключен к клиентскому сокету.
После того, как соединения установлены, связь может происходить с использованием потоков входных/выходных данных. Каждый сокет имеет и OutputStream (поток выходных данных), и InputStream (поток входных данных). OutputStream клиента подключен к InputStream сервера, а InputStream клиента подключен к OutputStream сервера.
TCP является двусторонним протоколом связи, поэтому данные могут передаваться по обоим потокам одновременно. Ниже приведены полезные классы, предоставляющие полный набор методов внедрения сокетов.
Конструкторы класса ServerSocket
Класс ServerSocket имеет четыре конструктора:
№ | Конструктор и описание |
1 | public ServerSocket(int port) throws IOException Попытки создания серверного сокета, связанного с указанным портом. Исключение происходит, если порт уже связан другим приложением. |
2 | public ServerSocket(int port, int backlog) throws IOException Как и в предыдущем конструкторе, параметр backlog указывает, сколько входящих клиентов нужно сохранить в очереди ожидания. |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException Как и в предыдущем конструкторе, параметр InetAddress указывает локальный IP-адрес для осуществления привязки. InetAddress используется в серверах, которые могут иметь несколько IP-адресов, что позволяет серверу указывать IP-адрес приема запросов клиентов. |
4 | public ServerSocket() throws IOException Создает непривязанный сокет сервера. При использовании этого конструктора используйте метод привязки (), когда будете готовы привязать сокет сервера. |
Если конструктор ServerSocket не выдает исключение, это означает, что ваше приложение успешно связано с указанным портом и готово к клиентским запросам.
Методы класса ServerSocket
Ниже приведены некоторые из распространенных методов в Java класса ServerSocket.
№ | Методы и описание |
1 | public int getLocalPort() Возвращает порт, который прослушивает сокет сервера. Этот метод полезен, если вы передали 0 в качестве номера порта в конструкторе и позволили серверу найти порт. |
2 | public Socket accept() throws IOException Ожидает входящего клиента. Этот метод блокируется до тех пор, пока клиент не подключится к серверу на указанном порту или не истечет время ожидания сокета, при условии, что значение времени ожидания было установлено с помощью метода setSoTimeout(). В противном случае этот метод блокируется на неопределенный срок. |
3 | public void setSoTimeout(int timeout) Устанавливает значение времени ожидания клиента сокетом сервера во время accept(). |
4 | public void bind (хост SocketAddress, int backlog) Привязывает сокет к указанному серверу и порту в объекте SocketAddress. Используйте этот метод, если вы создали ServerSocket с помощью конструктора без аргументов. |
Когда ServerSocket вызывает accept(), метод не возвращается, пока клиент не подключится. После того, как клиент все-таки подключится, ServerSocket создает новый сокет для неуказанного порта и возвращает ссылку на этот новый сокет. Теперь между клиентом и сервером существует TCP-соединение, и связь может установиться.
Конструкторы класса Socket
Класс Socket имеет пять конструкторов, которые клиент использует для подключения к серверу.
№ | Конструктор и описание |
1 | public Socket(String host, int port) throws UnknownHostException, IOException. Этот метод предпринимает попытку подключения к указанному серверу через указанный порт. Если этот конструктор не выдает исключение, то соединение установлено успешно, и клиент подключен к серверу. |
2 | public Socket(InetAddress host, int port) throws IOException Этот метод идентичен предыдущему конструктору, за исключением того, что хост обозначается объектом InetAddress. |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. Подключается к указанному хосту и порту, создавая сокет на локальном хосте по указанному адресу и порту. |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. Этот метод идентичен предыдущему конструктору, за исключением того, что хост обозначается объектом InetAddress вместо строки адреса. |
5 | public Socket() Создает неподключенный сокет. Используйте метод connect() для подключения такого сокета к серверу. |
При возврате конструктора Socket, он не просто создает экземпляр объекта сокета, но фактически пытается подключиться к указанному серверу и порту.
Некоторые методы, изучающие класс сокета, перечислены здесь. Обратите внимание, что и клиент, и сервер имеют объект сокета, поэтому эти методы могут вызываться как клиентом, так и сервером.
Методы класса Socket
Методы класса InetAddress
Этот класс представляет адрес Интернет-протокола (IP). Следующие полезные методы, которые понадобятся при программировании сокетов, представлены ниже:
№ | и описание |
1 | static InetAddress getByAddress(byte[] addr) Возвращает объект InetAddress с учетом необработанного IP-адреса. |
2 | static InetAddress getByAddress(String host, byte[] addr) Создает InetAddress на основе предоставленного имени хоста и IP-адреса. |
3 | static InetAddress getByName(String host) Определяет IP-адрес хоста, учитывая имя хоста. |
4 | String getHostAddress() Возвращает строку IP-адреса в текстовой форме. |
5 | String getHostName() Получает имя хоста для данного IP-адреса. |
6 | static InetAddress InetAddress getLocalHost() Возвращает локальный хост. |
7 | String toString() Конвертирует этот IP-адрес в адресную строку. |
Пример Socket Client
Следующая GreetingClient – это клиентская программа, которая подключается к серверу с помощью сокета, отправляет приветствие, а затем ожидает ответа.
Пример Socket Server
Следующая программа GreetingServer является примером серверного приложения, которое использует класс сокета для прослушивания клиентов по номеру порта, указанному в аргументе командной строки.
Скомпилируйте клиент и сервер, а затем запустите сервер следующим образом:
Вы хотите разработать сетевую программу на Джаве – игрушку, чат, или то и другое вместе… Вы нашли правильную статью – здесь вы сможете ознакомиться с захватывающим миром сокетов в Java. Прочитав эту статью, вам будет виден свет в конце туннеля – станет очевидным предназначение сокетов и то, как разработать простую программу с использованием сокетов на языке программирования Джава.
Что такое сокет?
На одном компьютере может параллельно исполняется несколько программ. Предположим, что вы запустили 10 программ на своем компьютере, и все они ожидают, чтоб другие компьютеры связались с ними. Можете представить себе это так: вас 10 человек в большом офисе с 1 телефоном и все ждут звонков от их собственных клиентов. Как вы это решите? Можно конечно назначить ответственного работника, и он будет приносить телефон соответственному человеку, которому звонят, но тогда другие клиенты не смогут дозвониться к другим людям. Кроме того, это очень трудно и нелепо иметь ответственного работника за маршрутизацию звонков к нужным людям. Вы должно быть, уже догадались, к чему я веду – если все эти программы, исполняющиеся на одном компьютере, с гордостью просят своих клиентов связаться с ними по определенному IP-адресу, то их клиенты не будут довольны. Идея состоит в следующем … иметь отдельный IP-адрес для каждой программы, верно? НЕ ВЕРНО! Суть вопроса не правильная – это также как спрашивать об отдельном офисе для каждого из вас. Ну, тогда … может отдельных телефонных номеров будет достаточно? ДА! На сетевом жаргоне "отдельные телефонные номера" имеют название порты. Порт – это просто число и каждая из программ, которая исполняется на определенном компьютере, может выбрать уникальное число порта, чтоб определить себя для внешнего мира. ЗАПОМНИТЕ – эти порты вы не сможете найти среди аппаратных средств компьютера (даже не старайтесь их искать). Эти числа – логические. Теперь все прояснилось: существует IP-адрес, с помощью которого другие компьютеры могут распознавать определенный компьютер в сети, и порт-число, которое определяет некую программу, работающую на компьютере. Также становиться понятным и то, что две программы на разных компьютерах могут использовать один и тот же порт (два дома на разных улицах тоже могут иметь один и тот самый номер, или нет?). Ну что же, мы практически у цели, только чтоб немного вас попугать, давайте выведем формулу:
Если сложить вместе выше описанные уравнения, то получим:
Если вы догадались до этого сами – значит мои усилия не пропали зря. Если нет, тогда прочитайте еще раз все сначала или воспользуйтесь Google для поиска лучшей статьи.
Подведем итог, сокет – это комбинация IP-адреса и порта. Сокет адрес надает возможность другим компьютерам в сети находить определенную программу, которая исполняется на определенном компьютере. Вы можете отображать сокет адрес вот так 64.104.137.58:80, где 64.104.137.58 – IP-адрес и 80 – порт.
Как программировать с использованием сокетов?
Достаточно о теории, давайте перейдем к действиям. Разработаем очень простой и наглядный код на Java, который продемонстрирует возможности использования сокетов. Попробуем реализовать следующий список действий:
1) Одна Джава программа будет пытаться связаться с другой Java программой (которая отчаянно ждет кого-то, чтоб с ней связался). Назовем первую программу Клиентом, а вторую Сервером.
2) После успешного связывания с сервером, клиент ждет ввода данных от вас и отсылает текст серверу.
3) Серверная программа отсылает клиенту назад тот ;t текст (для того чтоб показать, что она умеет делать даже такое полезное действие).
4) Полученный от сервера текст, клиент показывает вам, чтоб показать вам мнение сервера о вас. Приготовились приступить к разработке? Начнем. Отмечу только, что я не буду учить вас программированию на Java с чистого листа, а только объясню код, который относится к сокетам. Создайте 2 новых Джава программы и назовите их Server.java и Client.java. Я привел код ниже, только не пугайтесь, я все объясню.
Теперь скомпилируем код:
Откроем два командных окна (DOS). В одном окне введем:
Обязательно в таком порядке.
Теперь введите строку текста в окне, где запущен клиент, и нажмите кнопку Enter. Наблюдайте за двумя окнами и увидите что случиься. В конце, нажмите Ctrl-C для того чтоб остановить программы.
Объяснение кода работы с сокетами
Углубимся теперь немного в код. Вы уже уловили некоторые идеи, прочитав комментарии, но давайте проанализируем несколько критических строк кода.
Рассмотрим следующую часть кода сервера:
Класс ServerSocket немного отличается от класса Socket. Класс Socket – это и есть сокет. Главное отличие ServerSocket заключается в том, что он умеет заставлять программу ждать подключений от клиентов. Когда вы его создаете, нужно указывать порт, с которым он будет работать, и вызвать его метод accept(). Этот метод заставляет программу ждать подключений по указанному порту. Исполнение программы зависает в этом месте, пока клиент не подключится. После успешного подключения клиентом, создается нормальный Socket объект, который вы можете использовать для выполнения все существующий операций с сокетом. Заметим также, что этот Socket объект отображает другой конец соединения. Если вы хотите отослать данные клиенту, то вы не можете использовать для этого ваш собственный сокет.
Следующим рассмотрим Socket класс. Вы можете создать Socket объект, указав IP-адрес и порт. Вы можете использовать InetAddress класс для отображения IP-адреса (этот способ более предпочтительный). Для создания InetAddress объекта используйте следующий метод:
Заметим, что в нашей программе мы использовали адрес 127.0.0.1. Это специальный адрес называется адрес замыкания – он просто отображает локальный компьютер. Если вы намерены запустить клиент и сервер на разных компьютерах, тогда нужно использовать соответственный IP-адрес сервера.
После того как мы создали InetAddress, то можно создать Socket:
Следующие строки просто конвертируют потоки в другие типы потоков. После этого нам легче будет работать с String объектами. Этот код ничего не делает с сетью.
Все остальное очень просто – простые манипуляции с объектами потоков (никаких сокетов). Вы можете использовать ваши любимые потоки, вызывать ваши любимые методы, и удостоверяться в передаче данных во второй конец. Если вы не очень осведомлены в использовании потоков, рекомендую вам найти статью о них и прочесть.
Клиент-серверная архитектура — наиболее распространенная структура приложений в Интернете. В этой архитектуре клиенты (т.е. персональные компьютеры, устройства Интернета вещей и т. д.) сначала запрашивают ресурсы с сервера. Затем сервер отправляет обратно соответствующие ответы на запросы клиентов. Чтобы это произошло, должен быть какой-то механизм, реализованный как на стороне клиента, так и на стороне сервера, который поддерживает эту сетевую транзакцию. Этот механизм называется коммуникацией посредством сокетов.
Почти каждое приложение, которое пол а гается на сетевые операции, такие как извлечение данных с удаленных серверов и загрузка файлов на сервер, широко использует сокеты “под капотом”. Несколько примеров таких приложений — браузеры, чат-приложения и одноранговые сетевые приложения.
В этой статье мы более подробно рассмотрим сокеты и простую клиент-серверную реализацию с использованием сокетов в Java.
Примечание: существует два типа сокетов: TCP и UDP. Поскольку большинство сетевых приложений используют TCP, здесь я буду говорить только о TCP-сокетах и их реализации.
Сокет — это программная (логическая) конечная точка, устанавливающая двунаправленную коммуникацию между сервером и одной или несколькими клиентскими программами. Сокет — это нечто “программное”. Другими словами, сокет не существует на физическом уровне. Прикладное программное обеспечение определяет сокет так, чтобы он использовал порты на основном компьютере для его реализации. Это позволяет программистам комфортно работать с низкоуровневыми деталями сетевых коммуникаций, такими как порты, маршрутизация и т. д., внутри прикладного кода.
TCP-сокет устанавливает связь между клиентом и сервером в несколько этапов.
- Socket() — на сервере создается конечная точка для коммуникации.
- Bind() — сокету присваивается уникальный номер и для него резервируется уникальная комбинации IP-адреса и порта.
- Listen() — после создания сокета сервер ожидает подключения клиента.
- Accept() — сервер получает запрос на подключение от клиентского сокета.
- Connect() — клиент и сервер соединены друг с другом.
- Send()/Recieve() — обмен данными между клиентом и сервером.
- Close() — после обмена данными сервер и клиент разрывают соединение.
На каждой из перечисленных выше стадий коммуникации сокетов “под капотом" происходит много всего сложного. Однако этих знаний вполне достаточно для понимания и демонстрации того, как работает коммуникация посредством TCP-сокетов.
К настоящему времени мы уже достаточно знаем о TCP-сокетах. Давайте теперь посмотрим на них в действии.
Давайте посмотрим, как мы можем реализовать коммуникацию сокетов в Java. Мы сейчас напишем две Java-программы. Одной будет программа, запущенная на сервере, а другой — клиентская программа, которая будет взаимодействовать с сервером.
Реализация серверного сокета
В приведенной выше программе сервер открывает сокет с порта 50001 на серверной машине и ожидает клиента на server.accept() . После подключения клиента создается экземпляр выходного потока. Это может быть использовано для отправки данных с сервера на подключенный клиент. Именно это и делает serverOutput.writeBytes() . После отправки данных соединение с клиентом завершается.
Теперь давайте создадим клиент для взаимодействия с серверным сокетом, созданным выше.
Реализация клиентского сокета
Запуск программ
Сначала запустите серверную Java-программу, а затем клиентскую Java-программу (потому что сервер уже должен работать для подключения клиента). Вы увидите Received data: Java Revisited в терминале, где работает клиентская программа. Вот что здесь произошло: серверная программа отправила данные клиенту по запросу, а клиентская программа вывела их на терминал.
В этой статье мы обсудили, что такое сокеты и Java-реализация связи TCP-сокетов.
Что это такое программирование сокетов?
Сервер формирует слушателя, которого клиент обращается к серверу. Классы Socket и Server Socket используются для программирования сокетов с установлением соединения.
Что такое сокет?
Теперь, когда вы знаете, что такое Socket в Java, давайте продолжим и разберемся, как клиент взаимодействует с сервером и как сервер отвечает в ответ.
Клиентское программирование
В случае программирования на стороне клиента клиент сначала будет ждать запуска сервера. Как только сервер будет запущен, он отправит запросы на сервер. После этого клиент будет ждать ответа от сервера. Итак, в этом вся логика взаимодействия клиента и сервера.
Чтобы инициировать запрос клиентов, вам необходимо выполнить следующие шаги:
1. Установите соединение
Вы можете создать Socket с помощью следующего оператора:
- Здесь первый аргумент представляет собой IP-адрес сервера.
- Второй аргумент представляет TCP-порт (число, обозначающее, какое приложение должно работать на сервере).
2. Связь
Для связи через соединение сокета потоки используются как для ввода, так и для вывода данных. После установления соединения и отправки запросов вам необходимо закрыть соединение.
3. Закрытие соединения
Пример реализации сокетного соединения на стороне клиента
Программирование на стороне сервера
По сути, сервер создает экземпляр своего объекта и ждет запроса клиента. Как только клиент отправит запрос, сервер ответит на него.
Для кодирования серверного приложения вам понадобятся два сокета, и они следующие:
- ServerSocket, который ожидает клиентских запросов (когда клиент создает новый Socket()).
- Обычный старый сокет для связи с клиентом.
После этого вам нужно связаться с клиентом с ответом.
Общение
getOutputStream() используется для отправки вывода через сокет.
Закройте соединение
Когда все будет сделано, важно закрыть соединение, закрыв сокет, а также потоки ввода / вывода.
Пример реализации сокетного соединения на стороне сервера
1. Когда вы запускаете сценарий на стороне сервера, он запускается и ждет, пока клиент не запустится.
2. Затем клиент подключается и вводит запрос в виде строки.
3. Когда клиент отправляет запрос, сервер отвечает.
Вот как вам нужно выполнить программу сокета на Java. Вы также можете запускать эти программы в окне терминала или в командной строке. Но, поскольку Eclipse хорошо расширен своими функциями, вы можете просто запустить обе программы на консоли.
Клиент-серверная архитектура — наиболее распространенная структура приложений в Интернете. В этой архитектуре клиенты (т.е. персональные компьютеры, устройства Интернета вещей и т. д.) сначала запрашивают ресурсы с сервера. Затем сервер отправляет обратно соответствующие ответы на запросы клиентов. Чтобы это произошло, должен быть какой-то механизм, реализованный как на стороне клиента, так и на стороне сервера, который поддерживает эту сетевую транзакцию. Этот механизм называется коммуникацией посредством сокетов.
Почти каждое приложение, которое полагается на сетевые операции, такие как извлечение данных с удаленных серверов и загрузка файлов на сервер, широко использует сокеты “под капотом”. Несколько примеров таких приложений — браузеры, чат-приложения и одноранговые сетевые приложения.
В этой статье мы более подробно рассмотрим сокеты и простую клиент-серверную реализацию с использованием сокетов в Java.
Примечание: существует два типа сокетов: TCP и UDP. Поскольку большинство сетевых приложений используют TCP, здесь я буду говорить только о TCP-сокетах и их реализации.
Что такое сокет?
Сокет — это программная (логическая) конечная точка, устанавливающая двунаправленную коммуникацию между сервером и одной или несколькими клиентскими программами. Сокет — это нечто “программное”. Другими словами, сокет не существует на физическом уровне. Прикладное программное обеспечение определяет сокет так, чтобы он использовал порты на основном компьютере для его реализации. Это позволяет программистам комфортно работать с низкоуровневыми деталями сетевых коммуникаций, такими как порты, маршрутизация и т. д., внутри прикладного кода.
Как работают сокеты?
TCP-сокет устанавливает связь между клиентом и сервером в несколько этапов.
- Socket() — на сервере создается конечная точка для коммуникации.
- Bind() — сокету присваивается уникальный номер и для него резервируется уникальная комбинации IP-адреса и порта.
- Listen() — после создания сокета сервер ожидает подключения клиента.
- Accept() — сервер получает запрос на подключение от клиентского сокета.
- Connect() — клиент и сервер соединены друг с другом.
- Send()/Recieve() — обмен данными между клиентом и сервером.
- Close() — после обмена данными сервер и клиент разрывают соединение.
К настоящему времени мы уже достаточно знаем о TCP-сокетах. Давайте теперь посмотрим на них в действии.
Реализация коммуникации посредством TCP-сокетов в Java
Давайте посмотрим, как мы можем реализовать коммуникацию сокетов в Java. Мы сейчас напишем две Java-программы. Одной будет программа, запущенная на сервере, а другой — клиентская программа, которая будет взаимодействовать с сервером.
Реализация серверного сокета
В приведенной выше программе сервер открывает сокет с порта 50001 на серверной машине и ожидает клиента на server.accept() . После подключения клиента создается экземпляр выходного потока. Это может быть использовано для отправки данных с сервера на подключенный клиент. Именно это и делает serverOutput.writeBytes() . После отправки данных соединение с клиентом завершается.
Теперь давайте создадим клиент для взаимодействия с серверным сокетом, созданным выше.
Реализация клиентского сокета
Запуск программ
Сначала запустите серверную Java-программу, а затем клиентскую Java-программу (потому что сервер уже должен работать для подключения клиента). Вы увидите Received data: Java Revisited в терминале, где работает клиентская программа. Вот что здесь произошло: серверная программа отправила данные клиенту по запросу, а клиентская программа вывела их на терминал.
В этой статье мы обсудили, что такое сокеты и Java-реализация связи TCP-сокетов.
Читайте также: