В ОС Solaris для получения информации об используемых портах также применяется утилита netstat. Формат вывода практически одинаков.
Пакет java.net
Перейдем к рассмотрению средств Java для работы с сетью.
Классы, работающие с сетевыми протоколами, располагаются в пакете java.net, и простейшим из них является класс URL. С его помощью можно сконструировать uniform resource locator (URL), который имеет следующий формат:
protococlass="underline" //host:port/resource
Здесь protocol – название протокола, используемого для связи; host – IP-адрес, или DNS-имя сервера, к которому производится обращение; port – номер порта сервера (если порт не указан, то используется значение по умолчанию для указанного протокола);
resource – имя запрашиваемого ресурса, причем, оно может быть составным, например:
ftp://myserver.ru/pub/docs/Java/JavaCourse.txt
Затем можно воспользоваться методом openStream(), который возвращает InputStream, что позволяет считать содержимое ресурса. Например, следующая программа при помощи LineNumberReader считывает первую страницу сайта http://www.ru и выводит ее на консоль.
import java.io.*;
import java.net.*;
public class Net {
public static void main(String args[]) {
try {
URL url = new URL("http://www.ru");
LineNumberReader r =
new LineNumberReader(new
InputStreamReader(url.openStream()));
String s = r.readLine();
while (s!=null) {
System.out.println(s);
s = r.readLine();
}
System.out.println(r.getLineNumber());
r.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Из примера мы видим, что работа с сетью, как и работа с потоками, требует дополнительной работы с исключительными ситуациями. Ошибка MalformedURLException появляется в случае, если строка c URL содержит ошибки.
Более функциональным классом является URLConnection, который можно получить с помощью метода класса URL.openConnection(). У этого класса есть два метода – getInputStream() (именно с его помощью работает URL.openStream() ) и getOutputStream(), который можно использовать для передачи данных на сервер, если он поддерживает такую операцию (многие публичные web-серверы закрыты для таких действий).
Класс URLConnection является абстрактным. Виртуальная машина предоставляет реализации этого класса для каждого протокола, например, в том же пакете java.net определен класс HttpURLConnection. Понятно, что классы URL и URLConnection предоставляют возможность работы через сеть на прикладном уровне с помощью высокоуровневых протоколов.
Пакет java.net также предоставляет доступ к протоколам более низкого уровня – TCP и UDP. Для этого сначала надо ознакомиться с классом InetAddress, который является Internet-адресом, или IP. Экземпляры этого класса создаются не с помощью конструкторов, а с помощью статических методов:
InetAddress getLocalHost()
InetAddress getByName(String name)
InetAddress[] getAllByName(String name)
Первый метод возвращает IP-адрес машины, на которой исполняется Java- программа. Второй метод возвращает адрес сервера, чье имя передается в качестве параметра. Это может быть как DNS-имя, так и числовой IP, записанный в виде текста, например, "67.11.12.101". Наконец, третий метод определяет все IP-адреса указанного сервера.
Для работы с TCP-протоколом используются классы Socket и ServerSocket. Первым создается ServerSocket – сокет на стороне сервера. Его простейший конструктор имеет только один параметр – номер порта, на котором будут приниматься входящие запросы. После создания вызывается метод accept(), который приостанавливает выполнение программы и ожидает, пока какой-нибудь клиент не инициирует соединение. В этом случае работа сервера возобновляется, а метод возвращает экземпляр класса Socket для взаимодействия с клиентом:
try {
ServerSocket ss = new ServerSocket(3456);
Socket client=ss.accept();
// Метод не возвращает
// управление, пока не подключится клиент
}
catch (IOException e) {
e.printStackTrace();
}
Клиент для подключения к серверу также использует класс Socket. Его простейший конструктор принимает два параметра - адрес сервера (в виде строки, или экземпляра InetAddress ) и номер порта. Если сервер принял запрос, то сокет конструируется успешно и далее можно воспользоваться методами getInputStream() или getOutputStream().
try {
Socket s = new Socket("localhost", 3456);
InputStream is = s.getInputStream();
is.read();
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
Обратите внимание на обработку исключительной ситуации UnknownHostException, которая будет генерироваться, если виртуальная машина с помощью операционной системы не сможет распознать указанный адрес сервера в случае, если он задан строкой. Если же он задан экземпляром InetAddress, то эту ошибку надо обрабатывать при вызове статических методов данного класса.