|
||||||||
Программирование мобильных телефонов
Программирование на Java
|
Работа по протоколу TCP Программы-серверы, прослушивающие свои порты, работают под управлением операционной системы. У машин-серверов могут быть самые разные операционные системы, особенности которых передаются программам-серверам. Чтобы сгладить различия в реализациях разных серверов, между сервером и портом введен промежуточный программный слой, названный сокетом (socket). Английское слово socket переводится как электрический разъем, розетка. Так же как к розетке при помощи вилки можно подключить любой электрический прибор, лишь бы он был рассчитан на 220 В и 50 Гц, к соке-ту можно присоединить любой клиент, лишь бы он работал по тому же протоколу, что и сервер. Каждый сокет связан (bind) с одним портом, говорят, что сокет прослушивает (listen) порт. Соединение с помощью сокетов устанавливается так. 1. Сервер создает сокет, прослушивающий порт сервера. 2. Клиент тоже создает сокет, через который связывается с сервером, сервер начинает устанавливать (accept) связь с клиентом. 3. Устанавливая связь, сервер создает новый сокет, прослушивающий порт с другим, новым номером, и сообщает этот номер клиенту. 4. Клиент посылает запрос на сервер через порт с новым номером. После этого соединение становится совершенно симметричным — два сокета обмениваются информацией, а сервер через старый сокет продолжает прослушивать прежний порт, ожидая следующего клиента. В Java сокет — это объект класса socket из пакета java.io. В классе шесть конструкторов, в которые разными способами заносится адрес хоста и номер порта. Чаще всего применяется конструктор Socket(String host, int port) Многочисленные методы доступа устанавливают и получают параметры со-кета. Мы не будем углубляться в их изучение. Нам понадобятся только методы, создающие потоки ввода/вывода:
Приведем пример получения файла с сервера по максимально упрощенному протоколу HTTP. 1. Клиент посылает серверу запрос на получение файла строкой "POST filename HTTP/1.l\n\n", где filename — строка с путем к файлу на сервере. 2. Сервер анализирует строку, отыскивает файл с именем filename и возвращает его клиенту. Если имя файла filename заканчивается наклонной чертой /, то сервер понимает его как имя каталога и возвращает файл in-dex.html, находящийся в этом каталоге. 3. Перед содержимым файла сервер посылает строку вида "HTTP/1.1 code OK\n\n", где code — это код ответа, одно из чисел: 200 — запрос удовлетворен, файл посылается; 400 — запрос не понят; 404 — файл не найден. 4. Сервер закрывает сокет и продолжает слушать порт, ожидая следующего запроса. 5. Клиент выводит содержимое полученного файла в стандартный вывод System, out или выводит код сообщения сервера в стандартный вывод сообщений System, err. 6. Клиент закрывает сокет, завершая связь. Этот протокол реализуется в клиентской программе листинга 19.3 и серверной программе листинга 19.4. Листинг 19.3. Упрощенный HTTP-клиент import java.net.*; import java.io.*; import java.util.*; class Client{ public static void main(String[] args){ if (args.length != 3){ System.err.println("Usage: Client host port file"); System.exit(0) ; } String host = args[0]; int port = Integer.parselnt(args[1]); String file = args[2]; try{ Socket sock = new Socket(host, port); PrintWriter pw = new PrintWriter(new OutputStreamWriter( sock.getOutputStreamf)), true); pw.println("POST " + file + " HTTP/1.l\n"); BufferedReader br = new BufferedReader(new InputStreamReader( sock.getlnputStream() ) ) ; String line = null; line = br.readLine(); StringTokenizer st = new StringTokenizer(line); String code = null; if ((st.countTokens() >= 2) && st.nextToken().equals("POST")){ if ((code = st.nextToken()) != "200") { System.err.println("File not found, code = " + code); System.exit (0); } } while ((line = br.readLine()) != null) System.out.println{line); sock.close(); }catch(Exception e){ System.err.println(e); } } } Закрытие потоков ввода/вывода вызывает закрытие сокета. Обратно, закрытие сокета закрывает и потоки. Для создания сервера в пакете java.net есть класс serversocket. В конструкторе этого класса указывается номер порта ServerSocket(int port) Основной метод этого класса accept () ожидает поступления запроса. Когда запрос получен, метод устанавливает соединение с клиентом и возвращает объект класса socket, через который сервер будет обмениваться информацией с клиентом.
import j ava.net.*; import java.io.*; import j ava.uti1.*; class Server! public static void main(String[] args){ try{ ServerSocket ss = new ServerSocket(Integer.parselnt(args[0])); while (true) new HttpConnect(ss.accept()); }catch(ArraylndexOutOfBoundsException ae){ System.err.println("Usage: Server port"); System.exit(0); }catch(IOException e){ System.out.println(e); } } } class HttpConnect extends Thread{ private Socket sock; HttpConnect(Socket s) { sock = s; setPriority(NORM_PRIORITY - 1); start {) ; } public void run(){ try{ PrintWriter pw = new PrintWriter(new OutputStreamWriter( sock.getOutputStream()}, true); BufferedReader br = new BufferedReader(new InputStreamReader( sock.getlnputStream() ) ) ; String req = br.readLine(); System.out.println("Request: " + req); StringTokenizer st = new StringTokenizer(req); if ((st.countTokens() >= 2) && st.nextToken().equals("POST")){ if ((req = st.nextToken()).endsWith("/") II req.equals("")) req += "index.html"; try{ File f = new File(req); BufferedReader bfr = new BufferedReader(new FileReader(f)); char[] data = new char[(int)f.length()]; bfr.read(data); pw.println("HTTP/1.1 200 OK\n"); pw.write(data); pw.flush(); }catch(FileNotFoundException fe){ pw.println("HTTP/1.1 404 Not FoundXn"); }catch(lOException ioe){ System.out.println(ioe); } }else pw.println("HTTP/l.l 400 Bad RequestW); sock.close(); }catch(IOException e){ System.out.println(e); } } } Вначале следует запустить сервер, указав номер порта, например: Java Server 8080 Затем надо запустить клиент, указав IP-адрес или доменное имя хоста, номер порта и имя файла: Java Client localhost 8080 Server.Java Сервер отыскивает файл Server.java в своем текущем каталоге и посылает его клиенту. Клиент выводит содержимое этого класса в стандартный вывод и завершает работу. Сервер продолжает работать, ожидая следующего запроса. Замечание по отладке
|
|
||||||
Copyright © vzlom-1.ru 2020-2023
|