Глубокая расшифровка сведений о HTTP-соединении

TCP/IP

ПредыдущийстатьяВ , мы научились использовать wireshark и tcpdump для анализа «трехстороннего рукопожатия, четырехсторонней волны» TCP, который очень прост в использовании. Эти ребята легендарны锤子, держа锤子, видеть все как钉子! В этой статье я стремлюсьHTTPУдарь гвоздь вниз, гм.

Для более глубокого понимания «потока» сетевых пакетов я развернул на докере (удаленном) сервис, поддерживающий HTTP-вызовы. Запросите один из интерфейсов у клиента (локальный) в режиме http и получите данные ответа. В то же время перехватывайте пакеты локально через wireshark и перехватывайте пакеты удаленно с помощью tcpdump, а затем анализируйте все детали связи в процессе. Трагедия рвет прекрасное, а я рву сложное.

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

Для удобства чтения я вручную вставляю оглавление этой статьи:

blog dir

Перехват HTTP-сообщений

Введение

Теперь у меня есть служба, связанная с геогеометрией, которая предоставляет набор интерфейсов для внешнего использования. Один из интерфейсовFence2Area, Пользователь проходит в заборе (состоит из списка точек, точка представлена ​​), тип системы координат точки (Google Maps использует WGS84, отечественный Tencent и Autonavi Use SOSO, а Baidu использует Это еще один набор собственной системы координат), выход интерфейса является областью забора.

Запрашиваю интерфейс сервиса "Fence2Area", ввожу координаты вершин (lng, lat) забора (lng, lat), тип системы координат (coordtype), на выходе площадь полигона (площадь).

Обычный пример url запроса, который всем знаком (я использую docker_ip вместо реального ip):

http://docker_ip:7080/data?cmd=Fence2Area&meta={"caller":"test","TraceId":"test"}&request={"fence":[{"lng":10.2,"lat":10.2}, {"lng":10.2,"lat":8.2}, {"lng":8.2,"lat":8.2}, {"lng":8.2,"lat":10.2}],"coordtype":2}

После отправки запроса сервер обрабатывает его, а затем клиент получает возвращенные данные следующим образом:

{
    "data": {
        "area": 48764135597.842606
    },
    "errstr": ""
}

areaполе представляет площадь,errstrУказывает на сообщение об ошибке, пустое значение означает отсутствие ошибки.

захват пакетов

Перед отправкой фактического запроса настройки перед захватом пакета. На локальном Mac я использую Wireshark; на удаленном документе я использую инструмент TCPDUMP.

Локальный Mac

Настройте фильтры пакетов wireshark для мониторинга обмена данными между локальным хостом и удаленным докером.

ip.addr eq docker_ip

Нажмите, чтобы начать захват.

удаленный докер

Услуга предоставляется извне через порт 7080. Используйте следующую команду для захвата сетевых пакетов:

tcpdump -w /tmp/testHttp.cap port 7080 -s0

Запрос && анализ

Подготовительная работа сделала, я выбрал священный момент, посетите следующий браузер URL локально:

http://docker_ip:7080/data?cmd=Fence2Area&meta={"caller":"test","TraceId":"test"}&request={"fence":[{"lng":10.2,"lat":10.2}, {"lng":10.2,"lat":8.2}, {"lng":8.2,"lat":8.2}, {"lng":8.2,"lat":10.2}],"coordtype":2}

Таким образом, как локальный wireshark, так и удаленный tcpdump могут перехватывать сетевые пакеты HTTP.

Закрыть сервисный процесс

Прежде чем сделать официальный запрос, давайте рассмотрим несколько особых случаев.

Сначала закройте процесс службы gcs и запросите возврат RST-сообщения напрямую.

rst

Как показано выше, когда я запрашиваю, я обращаюсь к другому порту на стороне сервера.5010, На этом порту не прослушивается служба, что имеет тот же эффект, что и закрытие процесса службы gcs. Видно, что клиент отправляет сообщение SYN, но оно напрямую удаляется удаленным докером RST. Потому что операционная система сервера не может найти процесс, прослушивающий этот порт.

закрыть докер

Закройте докер, потому что на отправленный сегмент SYN нельзя ответить, поэтому он будет повторять попытку, а количество попыток под mac равно 10 раз.

mac retry

Сначала повторялись 5 раз каждую 1 секунду, а затем повторялись с интервалом «экспоненциальной отсрочки», 2 с, 4 с, 8 с, 16 с, 32 с. Наконец закончилось.

перезапустить докер

Сначала сделайте обычный доступ, затем перезапустите докер. И снова получите доступ к указанному выше URL-адресу локально, браузер по-прежнему использует последний порт в это время.После доступа к серверу, поскольку он был перезапущен, сервер не имеет новостей об этом соединении. Поэтому возвращается сообщение RST.

нормальный запрос

Служба запускается нормально, запрос отправляется нормально, на этот раз запрос прошел успешно, конечно, хе-хе!

normal_req_wireshark

Это пакет данных, захваченный с помощью wireshark на Mac, всего 7 пакетов, первые три пакета представляют собой пакеты трехстороннего рукопожатия, а четвертый пакетHTTPДанные запроса, отправленные уровнем, пятый пакет — это сообщение подтверждения TCP сервера, а шестой пакет — это сообщение сервера.HTTPДанные ответа, отправленные уровнем, седьмой пакет являются сообщением подтверждения Mac для шестого пакета.

Давайте сосредоточимся на следующих пакетах, давайте сначала посмотрим на четвертый пакет,

0x0000:  4500 0295 0000 4000 3606 623b ac17 ccdc
0x0010:  0a60 5cd4 db9b 1ba8 a59a 46ce 6d03 e87d
0x0020:  8018 1015 0ee7 0000 0101 080a 2e4c b2ef
0x0030:  0f20 3acf 4745 5420 2f64 6174 613f 636d
0x0040:  643d 4665 6e63 6532 4172 6561 266d 6574
0x0050:  613d 7b25 3232 6361 6c6c 6572 2532 323a
0x0060:  2532 3274 6573 7425 3232 2c25 3232 5472
0x0070:  6163 6549 6425 3232 3a25 3232 7465 7374
0x0080:  2532 327d 2672 6571 7565 7374 3d7b 2532
0x0090:  3266 656e 6365 2532 323a 5b7b 2532 326c
0x00a0:  6e67 2532 323a 3130 2e32 2c25 3232 6c61
0x00b0:  7425 3232 3a31 302e 327d 2c25 3230 7b25
0x00c0:  3232 6c6e 6725 3232 3a31 302e 322c 2532
0x00d0:  326c 6174 2532 323a 382e 327d 2c25 3230
0x00e0:  7b25 3232 6c6e 6725 3232 3a38 2e32 2c25
0x00f0:  3232 6c61 7425 3232 3a38 2e32 7d2c 2532
0x0100:  307b 2532 326c 6e67 2532 323a 382e 322c
0x0110:  2532 326c 6174 2532 323a 3130 2e32 7d5d
0x0120:  2c25 3232 636f 6f72 6474 7970 6525 3232
0x0130:  3a32 7d20 4854 5450 2f31 2e31 0d0a 486f
0x0140:  7374 3a20 3130 2e39 362e 3932 2e32 3132
0x0150:  3a37 3038 300d 0a55 7067 7261 6465 2d49
0x0160:  6e73 6563 7572 652d 5265 7175 6573 7473
0x0170:  3a20 310d 0a41 6363 6570 743a 2074 6578
0x0180:  742f 6874 6d6c 2c61 7070 6c69 6361 7469
0x0190:  6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070
0x01a0:  6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30
0x01b0:  2e39 2c2a 2f2a 3b71 3d30 2e38 0d0a 5573
0x01c0:  6572 2d41 6765 6e74 3a20 4d6f 7a69 6c6c
0x01d0:  612f 352e 3020 284d 6163 696e 746f 7368
0x01e0:  3b20 496e 7465 6c20 4d61 6320 4f53 2058
0x01f0:  2031 305f 3133 5f36 2920 4170 706c 6557
0x0200:  6562 4b69 742f 3630 352e 312e 3135 2028
0x0210:  4b48 544d 4c2c 206c 696b 6520 4765 636b
0x0220:  6f29 2056 6572 7369 6f6e 2f31 322e 302e
0x0230:  3220 5361 6661 7269 2f36 3035 2e31 2e31
0x0240:  350d 0a41 6363 6570 742d 4c61 6e67 7561
0x0250:  6765 3a20 7a68 2d63 6e0d 0a41 6363 6570
0x0260:  742d 456e 636f 6469 6e67 3a20 677a 6970
0x0270:  2c20 6465 666c 6174 650d 0a43 6f6e 6e65
0x0280:  6374 696f 6e3a 206b 6565 702d 616c 6976
0x0290:  650d 0a0d 0a

Давайте проанализируем байт за байтом.

значение байта Значение байта
0x4 IP версия ipv4
0x5 Длина заголовка 5 * 4 байта = 20 байт.
0x00 Тип службы, теперь в основном установлен на 0
0x0295 Общая длина 661 байт, то есть длина всего пакета 661 байт
0x0000 логотип. Уникальный идентификатор той же дейтаграммы. Когда дейтаграмма IP разделена, она копируется в каждую дейтаграмму.
0x4000 3bit 标志 + 13bit 片偏移. 3-битные флаги соответствуют R, DF и MF. В настоящее время действительны только последние два бита, бит DF: 1 означает отсутствие фрагментации, 0 означает фрагментацию. MF: 1 означает «больше фрагментов», 0 означает, что это последний фрагмент. 13-битное смещение фрагмента: Бит смещения этого фрагмента относительно первой позиции в исходном пакете данных. (нужно умножить на 8)
0x36 Время жить TTL. Максимальное количество маршрутизаторов, через которые разрешено проходить IP-пакетам. Каждый раз, когда маршрутизатор проходит, значение TTL уменьшается на 1. Когда оно равно 0, маршрутизатор отбрасывает дейтаграмму. Поле TTL представляет собой 8-битное поле, первоначально установленное отправителем.Рекомендуемое начальное значение указано в RFC Assign Numbers. Эхо-ответы ICMP часто отправляются с максимальным значением TTL, равным 255. TTL предотвращает застревание дейтаграмм в петлях маршрутизации. 54 здесь.
0x06 тип соглашения. Укажите, какой протокол используется для данных, переносимых IP-пакетом, чтобы уровень IP узла назначения мог знать, какому процессу отправить пакет данных. Номер протокола TCP — 6, номер протокола UDP — 17. Номер протокола ICMP — 1, номер протокола IGMP — 2. Данные, переносимые в IP-пакете, используют протокол TCP и были проверены.
0x623b 16-битная контрольная сумма заголовка IP.
0xac17 ccdc 32-битный исходный IP-адрес.
0x0a60 5cd4 32-битный IP-адрес назначения.

Оставшаяся часть данных относится к протоколу TCP. TCP также имеет фиксированную длину 20 байт + часть переменной длины.

значение байта Значение байта
0xdb9b 16-битный исходный порт. 56219
0x1ba8 16-битный порт назначения 7080
0xa59a 46ce 32-битный серийный номер. 2778351310
0x6d03 e87d 32-битный номер подтверждения. 1828972669
0x8 Длина заголовка 4 бита, в блоках по 4 байта. Всего 8*4=32 байта. Следовательно, необязательная длина сообщения TCP составляет 32-20 = 12 байт.
0b000000 6-битные зарезервированные биты. В настоящее время установлено значение 0.
0b011000 Бит флага 6bitTCP. Слева направо: Emergency URG, Acknowledge ACK, Push PSH, Reset RST, Synchronize SYN, Terminate FIN. ack действителен, а psh действителен
0x1015 Размер скользящего окна, скользящее окно — это размер буфера приема tcp, который используется для управления перегрузкой tcp. 4117.
0x0ee7 16-битная контрольная сумма.
0x0000 Аварийный указатель. Он имеет смысл только при URG = 1, он указывает количество байтов экстренных данных в этом отчете. Когда URG = 1, TCP-отправитель вставляет экстренные данные в начало информационных данных, а данные после экстренных данных по-прежнему являются обычными данными.

Часть переменной длины, протокол выглядит следующим образом:

значение байта Значение байта
0x01 бездействие
0x01 бездействие
0x0402 Указывает на поддержку SACK
0x080a 2e4c b2ef 0f20 3acf метка времени. Ts val=0x2e4c b2ef=776778479, ecr=0x0f20 3acf=253770447

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

man ascii

Вы можете получить код ascii, давайте посмотрим непосредственно на шестнадцатеричный результат:

ascii

адрес начала строки байтовый поток персонаж
0x0030 4745 5420 2f64 6174 613f 636d GE T /d at a? cm
0x0040 643d 4665 6e63 6532 4172 6561 266d 6574 d= Fe nc e2 Ar ea &m et
0x0050 613d 7b25 3232 6361 6c6c 6572 2532 323a a= {% 22 ca ll er %2 2:
0x0060 2532 3274 6573 7425 3232 2c25 3232 5472 %2 2t es t% 22 ,% 22 Tr
0x0070 6163 6549 6425 3232 3a25 3232 7465 7374 ac eI d% 22 :% 22 te st
0x0080 2532 327d 2672 6571 7565 7374 3d7b 2532 %2 2} &r eq ue st ={ %2
0x0090 3266 656e 6365 2532 323a 5b7b 2532 326c 2f en ce %2 2: [{ %2 2l
0x00a0 6e67 2532 323a 3130 2e32 2c25 3232 6c61 ng %2 2: 10 .2 ,% 22 la
0x00b0 7425 3232 3a31 302e 327d 2c25 3230 7b25 t% 22 :1 0. 2} ,% 20 {%
0x00c0 3232 6c6e 6725 3232 3a31 302e 322c 2532 22 ln g% 22 :1 0. 2, %2
0x00d0 326c 6174 2532 323a 382e 327d 2c25 3230 2l at %2 2: 8. 2} ,% 20
0x00e0 7b25 3232 6c6e 6725 3232 3a38 2e32 2c25 {% 22 ln g% 22 :8 .2 ,%
0x00f0 3232 6c61 7425 3232 3a38 2e32 7d2c 2532 22 la t% 22 :8 .2 }, %2
0x0100 307b 2532 326c 6e67 2532 323a 382e 322c 0{ %2 2l ng %2 2: 8. 2,
0x0110 2532 326c 6174 2532 323a 3130 2e32 7d5d %2 2l at %2 2: 10 .2 } ]
0x0120 2c25 3232 636f 6f72 6474 7970 6525 3232 ,% 22 co or dt yp e% 22
0x0130 3a32 7d20 4854 5450 2f31 2e31 0d0a 486f :2 } HT TP /1 .1 crnl Ho
0x0140 7374 3a20 3130 2e39 362e 3932 2e32 3132 st : 10 .9 6. 92 .2 12
0x0150 3a37 3038 300d 0a55 7067 7261 6465 2d49 :7 08 0cr nlU pg ra de -I
0x0160 6e73 6563 7572 652d 5265 7175 6573 7473 ns ec ur e- Re qu es ts
0x0170 3a20 310d 0a41 6363 6570 743a 2074 6578 : 1cr nlA cc ep t: t ex
0x0180 742f 6874 6d6c 2c61 7070 6c69 6361 7469 t/ ht ml ,a pp li ca ti
0x0190 6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070 on /x ht ml +x ml ,a pp
0x01a0 6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30 li ca ti on /x ml ;q =0
0x01b0 2e39 2c2a 2f2a 3b71 3d30 2e38 0d0a 5573 .9 ,* /* ;q =0 .8 crnl Us
0x01c0 6572 2d41 6765 6e74 3a20 4d6f 7a69 6c6c er -A ge nt : Mo zi ll
0x01d0 612f 352e 3020 284d 6163 696e 746f 7368 a/ 5. 0 (M ac in to sh
0x01e0 3b20 496e 7465 6c20 4d61 6320 4f53 2058 ; In te l Ma c OS X
0x01f0 2031 305f 3133 5f36 2920 4170 706c 6557 1 0_ 13 _6 ) Ap pl eW
0x0200 6562 4b69 742f 3630 352e 312e 3135 2028 eb Ki t/ 60 5. 1. 15 (
0x0210 4b48 544d 4c2c 206c 696b 6520 4765 636b KH TM L, l i k e Ge ck
0x0220 6f29 2056 6572 7369 6f6e 2f31 322e 302e o) V er si o n /1 2. 0.
0x0230 3220 5361 6661 7269 2f36 3035 2e31 2e31 2 Sa fa ri /6 05 .1 .1
0x0240 350d 0a41 6363 6570 742d 4c61 6e67 7561 5cr nlA cc ep t- La ng ua
0x0250 6765 3a20 7a68 2d63 6e0d 0a41 6363 6570 ge : zh -c ncr nlA cc ep
0x0260 742d 456e 636f 6469 6e67 3a20 677a 6970 t- En co di ng : gz ip
0x0270 2c20 6465 666c 6174 650d 0a43 6f6e 6e65 , de fl at ecr nlC on ne
0x0280 6374 696f 6e3a 206b 6565 702d 616c 6976 ct io n: k ee p- al iv
0x0290 650d 0a0d 0a ecr nl cr nl

Объединение последнего столбца таблицы выше:

GET /data?cmd=Fence2Area&meta={%22caller%22:%22test%22,%22TraceId%22:%22test%22}&request={%22fence%22:[{%22lng%22:10.2,%22lat%22:10.2},%20{%22lng%22:10.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:10.2}],%22coordtype%22:2} HTTP/1.1 
Host: 10.96.92.212:7080 
Upgrade-Insecure-Requests: 1 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15 
Accept-Language: zh-cn 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
 

Среди них cr nl означает возврат каретки, перевод строки.

После того, как докер получит данные, он ответит пакетом подтверждения. Общая длина четвертого пакета составляет 661 байт, исключая 20-байтовый IP-заголовок, 20-байтовую фиксированную часть TCP-заголовка и необязательную длину TCP-заголовка 12 байтов, всего 52 байта. общая длина части данных TCP составляет 52 байта Длина 661-52=609 байт. Также серийный номер 2778351310.

Глядя на пятый пакет, поток байтов выглядит следующим образом:

0x0000:  4500 0034 d28b 4000 4006 8810 0a60 5cd4
0x0010:  ac17 ccdc 1ba8 db9b 6d03 e87d a59a 492f
0x0020:  8010 00ec e04e 0000 0101 080a 0f20 3af7
0x0030:  2e4c b2ef
значение байта Значение байта
0x4 IP версия ipv4
0x5 Длина заголовка 5 * 4 байта = 20 байт.
0x00 Тип службы, теперь в основном установлен на 0
0x0034 Общая длина 52 байта, то есть длина всего пакета 52 байта
0xd28b логотип. Уникальный идентификатор той же дейтаграммы. Когда дейтаграмма IP разделена, она копируется в каждую дейтаграмму.
0x4000 3bit 标志 + 13bit 片偏移. 3-битные флаги соответствуют R, DF и MF. В настоящее время действительны только последние два бита, бит DF: 1 означает отсутствие фрагментации, 0 означает фрагментацию. MF: 1 означает «больше фрагментов», 0 означает, что это последний фрагмент. 13-битное смещение фрагмента: Бит смещения этого фрагмента относительно первой позиции в исходном пакете данных. (нужно умножить на 8)
0x40 Время жить TTL. Максимальное количество маршрутизаторов, через которые разрешено проходить IP-пакетам. Каждый раз, когда маршрутизатор проходит, значение TTL уменьшается на 1. Когда оно равно 0, маршрутизатор отбрасывает дейтаграмму. Поле TTL представляет собой 8-битное поле, первоначально установленное отправителем.Рекомендуемое начальное значение указано в RFC Assign Numbers. Эхо-ответы ICMP часто отправляются с максимальным значением TTL, равным 255. TTL предотвращает застревание дейтаграмм в петлях маршрутизации. 54 здесь.
0x06 тип соглашения. Укажите, какой протокол используется для данных, переносимых IP-пакетом, чтобы уровень IP узла назначения мог знать, какому процессу отправить пакет данных. Номер протокола TCP — 6, номер протокола UDP — 17. Номер протокола ICMP — 1, номер протокола IGMP — 2. Данные, переносимые в IP-пакете, используют протокол TCP и были проверены.
0x8810 16-битная контрольная сумма заголовка IP.
0x0a60 5cd4 32-битный исходный IP-адрес.
0xac17 ccdc 32-битный IP-адрес назначения.

Оставшаяся часть данных относится к протоколу TCP. TCP также имеет фиксированную длину 20 байт + часть переменной длины.

значение байта Значение байта
0x1ba8 16-битный исходный порт 7080
0xdb9b 16-битный порт назначения. 56219
0x6d03 e87d 32-битный серийный номер. 1828972669
0xa59a 492f 32-битный номер подтверждения. 2778351919. Серийный номер третьего пакета 2778351310 плюс длина данных 609, что в точности равно.
0x8 Длина заголовка 4 бита, в блоках по 4 байта. Всего 8*4=32 байта. Следовательно, необязательная длина сообщения TCP составляет 32-20 = 12 байт.
0b000000 6-битные зарезервированные биты. В настоящее время установлено значение 0.
0b010000 Бит флага 6bitTCP. Слева направо: Emergency URG, Acknowledge ACK, Push PSH, Reset RST, Synchronize SYN, Terminate FIN. подтверждение действительно
0x00ec Размер скользящего окна, скользящее окно — это размер буфера приема tcp, который используется для управления перегрузкой tcp. 4117
0xe04e 16-битная контрольная сумма.
0x0000 Аварийный указатель. Имеет значение, только если URG = 1, указывает количество байтов срочных данных в этом сегменте. Когда URG = 1, TCP отправителя вставляет срочные данные в начало данных в этом сегменте, а данные после срочных данных остаются обычными данными.

Часть переменной длины, протокол выглядит следующим образом:

значение байта Значение байта
0x01 бездействие
0x01 бездействие
0x0402 Указывает на поддержку SACK
0x080a 2e4c b2ef 0f20 3acf метка времени. Тс знач=253770487, экр=776778479

Часть данных пуста, этот пакет является только пакетом подтверждения.

Посмотрите на шестой пакет, поток байтов выглядит следующим образом:

0x0000:  4500 00f9 d28c 4000 4006 874a 0a60 5cd4
0x0010:  ac17 ccdc 1ba8 db9b 6d03 e87d a59a 492f
0x0020:  8018 00ec e113 0000 0101 080a 0f20 3af8
0x0030:  2e4c b2ef 4854 5450 2f31 2e31 2032 3030
0x0040:  204f 4b0d 0a41 6363 6573 732d 436f 6e74
0x0050:  726f 6c2d 416c 6c6f 772d 4f72 6967 696e
0x0060:  3a20 2a0d 0a44 6174 653a 2054 6875 2c20
0x0070:  3033 204a 616e 2032 3031 3920 3132 3a32
0x0080:  333a 3437 2047 4d54 0d0a 436f 6e74 656e
0x0090:  742d 4c65 6e67 7468 3a20 3438 0d0a 436f
0x00a0:  6e74 656e 742d 5479 7065 3a20 7465 7874
0x00b0:  2f70 6c61 696e 3b20 6368 6172 7365 743d
0x00c0:  7574 662d 380d 0a0d 0a7b 2264 6174 6122
0x00d0:  3a7b 2261 7265 6122 3a34 3837 3634 3133
0x00e0:  3535 3937 2e38 3432 3630 367d 2c22 6572
0x00f0:  7273 7472 223a 2222 7d
значение байта Значение байта
0x4 IP версия ipv4
0x5 Длина заголовка 5 * 4 байта = 20 байт.
0x00 Тип службы, теперь в основном установлен на 0
0x00f9 Общая длина 249 байт, то есть длина всего пакета 249 байт.
0xd28c логотип. Уникальный идентификатор той же дейтаграммы. Когда дейтаграмма IP разделена, она копируется в каждую дейтаграмму.
0x4000 3bit 标志 + 13bit 片偏移. 3-битные флаги соответствуют R, DF и MF. В настоящее время действительны только последние два бита, бит DF: 1 означает отсутствие фрагментации, 0 означает фрагментацию. MF: 1 означает «больше фрагментов», 0 означает, что это последний фрагмент. 13-битное смещение фрагмента: Бит смещения этого фрагмента относительно первой позиции в исходном пакете данных. (нужно умножить на 8)
0x40 Время жить TTL. Максимальное количество маршрутизаторов, через которые разрешено проходить IP-пакетам. Каждый раз, когда маршрутизатор проходит, значение TTL уменьшается на 1. Когда оно равно 0, маршрутизатор отбрасывает дейтаграмму. Поле TTL представляет собой 8-битное поле, первоначально установленное отправителем.Рекомендуемое начальное значение указано в RFC Assign Numbers. Эхо-ответы ICMP часто отправляются с максимальным значением TTL, равным 255. TTL предотвращает застревание дейтаграмм в петлях маршрутизации. Вот 64.
0x06 тип соглашения. Укажите, какой протокол используется для данных, переносимых IP-пакетом, чтобы уровень IP узла назначения мог знать, какому процессу отправить пакет данных. Номер протокола TCP — 6, номер протокола UDP — 17. Номер протокола ICMP — 1, номер протокола IGMP — 2. Данные, переносимые в IP-пакете, используют протокол TCP и были проверены.
0x874a 16-битная контрольная сумма заголовка IP.
0x0a60 5cd4 32-битный исходный IP-адрес.
0xac17 ccdc 32-битный IP-адрес назначения.

Оставшаяся часть данных относится к протоколу TCP. TCP также имеет фиксированную длину 20 байт + часть переменной длины.

значение байта Значение байта
0x1ba8 16-битный исходный порт 7080
0xdb9b 16-битный порт назначения. 56219
0x6d03 e87d 32-битный серийный номер. 1828972669
0xa59a 492f 32-битный номер подтверждения. 2778351919
0x8 Длина заголовка 4 бита, в блоках по 4 байта. Всего 8*4=32 байта. Следовательно, необязательная длина сообщения TCP составляет 32-20 = 12 байт.
0b000000 6-битные зарезервированные биты. В настоящее время установлено значение 0.
0b011000 Бит флага 6bitTCP. Слева направо: Emergency URG, Acknowledge ACK, Push PSH, Reset RST, Synchronize SYN, Terminate FIN. ack действителен, а psh действителен
0x00ec Размер скользящего окна, скользящее окно — это размер буфера приема tcp, который используется для управления перегрузкой tcp. 236
0xe113 16-битная контрольная сумма.
0x0000 Аварийный указатель. Имеет значение, только если URG = 1, указывает количество байтов срочных данных в этом сегменте. Когда URG = 1, TCP отправителя вставляет срочные данные в начало данных в этом сегменте, а данные после срочных данных остаются обычными данными.

Часть переменной длины, протокол выглядит следующим образом:

значение байта Значение байта
0x01 бездействие
0x01 бездействие
0x0402 Указывает на поддержку SACK
0x080a 0f20 3af8 2e4c b2ef метка времени. Ts val=0x2e4c b2ef=253770488, ecr=0x0f20 3acf=776778479

Остается только часть данных. Смотрим строчку за строчкой.

первый адрес байтовый поток персонаж
0x0030 4854 5450 2f31 2e31 2032 3030 HTTP/1.1 200
0x0040 204f 4b0d 0a41 6363 6573 732d 436f 6e74 OK \r\n Access-Cont
0x0050 726f 6c2d 416c 6c6f 772d 4f72 6967 696e rol-Allow-Origin
0x0060 3a20 2a0d 0a44 6174 653a 2054 6875 2c20 : * \r\n Date: Thu,
0x0070 3033 204a 616e 2032 3031 3920 3132 3a32 03 Jan 2019 12:2
0x0080 333a 3437 2047 4d54 0d0a 436f 6e74 656e 3:47 GMT \r\n Conten
0x0090 742d 4c65 6e67 7468 3a20 3438 0d0a 436f t-Length: 48\r\n Co
0x00a0 6e74 656e 742d 5479 7065 3a20 7465 7874 ntent-Type: text
0x00b0 2f70 6c61 696e 3b20 6368 6172 7365 743d /plain; charset=
0x00c0 7574 662d 380d 0a0d 0a7b 2264 6174 6122 utf-8\r\n\r\n{"data"
0x00d0 3a7b 2261 7265 6122 3a34 3837 3634 3133 :{"area":4876413
0x00e0 3535 3937 2e38 3432 3630 367d 2c22 6572 5597.842606},"er
0x00f0 7273 7472 223a 2222 7d rstr":""}

Объединение последнего столбца таблицы выше:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: * 
Date: Thu, 03 Jan 2019 12:23:47 GMT 
Content-Length: 48 
Content-Type: text/plain; charset=utf-8 
{"data":{"area":48764135597.842606},"errstr":""}

Длина содержимого: 48, длина последней строки, которая составляет 48 байтов.

Наконец, седьмой пакет, поток байтов выглядит следующим образом:

0x0000:  4500 0034 0000 4000 3606 649c ac17 ccdc
0x0010:  0a60 5cd4 db9b 1ba8 a59a 492f 6d03 e942
0x0020:  8010 100f 1eb9 0000 0101 080a 2e4c b314
0x0030:  0f20 3af8
значение байта Значение байта
0x4 IP версия ipv4
0x5 Длина заголовка 5 * 4 байта = 20 байт.
0x00 Тип службы, теперь в основном установлен на 0
0x0034 Общая длина 52 байта, то есть длина всего пакета 52 байта
0x0000 логотип. Уникальный идентификатор той же дейтаграммы. Когда дейтаграмма IP разделена, она копируется в каждую дейтаграмму.
0x4000 3bit 标志 + 13bit 片偏移. 3-битные флаги соответствуют R, DF и MF. В настоящее время действительны только последние два бита, бит DF: 1 означает отсутствие фрагментации, 0 означает фрагментацию. MF: 1 означает «больше фрагментов», 0 означает, что это последний фрагмент. 13-битное смещение фрагмента: Бит смещения этого фрагмента относительно первой позиции в исходном пакете данных. (нужно умножить на 8)
0x36 Время жить TTL. Максимальное количество маршрутизаторов, через которые разрешено проходить IP-пакетам. Каждый раз, когда маршрутизатор проходит, значение TTL уменьшается на 1. Когда оно равно 0, маршрутизатор отбрасывает дейтаграмму. Поле TTL представляет собой 8-битное поле, первоначально установленное отправителем.Рекомендуемое начальное значение указано в RFC Assign Numbers. Эхо-ответы ICMP часто отправляются с максимальным значением TTL, равным 255. TTL предотвращает застревание дейтаграмм в петлях маршрутизации. 54 здесь.
0x06 тип соглашения. Укажите, какой протокол используется для данных, переносимых IP-пакетом, чтобы уровень IP узла назначения мог знать, какому процессу отправить пакет данных. Номер протокола TCP — 6, номер протокола UDP — 17. Номер протокола ICMP — 1, номер протокола IGMP — 2. Данные, переносимые в IP-пакете, используют протокол TCP и были проверены.
0x649c 16-битная контрольная сумма заголовка IP.
0xac17 ccdc 32-битный исходный IP-адрес.
0x0a60 5cd4 32-битный IP-адрес назначения.

Оставшаяся часть данных относится к протоколу TCP. TCP также имеет фиксированную длину 20 байт + часть переменной длины.

значение байта Значение байта
0xdb9b 16-битный исходный порт. 56219
0x1ba8 16-битный порт назначения 7080
0xa59a 492f 32-битный серийный номер. 2778351919
0x6d03 e942 32-битный номер подтверждения. 1828972866. Серийный номер шестого пакета 1828972669 плюс длина данных 197, что в точности равно
0x8 Длина заголовка 4 бита, в блоках по 4 байта. Всего 8*4=32 байта. Следовательно, необязательная длина сообщения TCP составляет 32-20 = 12 байт.
0b000000 6-битные зарезервированные биты. В настоящее время установлено значение 0
0b010000 Бит флага 6bitTCP. Слева направо: Emergency URG, Acknowledge ACK, Push PSH, Reset RST, Synchronize SYN, Terminate FIN. подтверждение действительно
0x100f Размер скользящего окна, скользящее окно — это размер буфера приема tcp, который используется для управления перегрузкой tcp. 4111
0x1eb9 16-битная контрольная сумма.
0x0000 Аварийный указатель. Имеет значение, только если URG = 1, указывает количество байтов срочных данных в этом сегменте. Когда URG = 1, TCP отправителя вставляет срочные данные в начало данных в этом сегменте, а данные после срочных данных остаются обычными данными.

Часть переменной длины, протокол выглядит следующим образом:

значение байта Значение байта
0x01 бездействие
0x01 бездействие
0x080a 2e4c b314 0f20 3af8 метка времени. Значение Ts=0x2e4c b314=776778516, ECR=0x0f20 3af8=253770488

На данный момент было проанализировано полное сообщение HTTP-запроса. Как вы себя чувствуете, это мило?

Анализ HTTP-протокола

Выше мы разобрали данные, относящиеся к протоколу HTTP.Далее я сравню результаты приведенной выше разборки данных и шаг за шагом проведу вас к более глубокому пониманию протокола HTTP.

Общее введение

HTTP(Протокол передачи гипертекста) Протокол передачи гипертекста — это протокол, используемый для связи в Интернете. Если выразиться более образно:HTTPэто общий язык, используемый в современном Интернете. Его самое известное приложение предназначено для связи между сервером браузера.

HTTP — это протокол прикладного уровня, а нижний уровень полагается на TCP для надежной передачи информации.

HTTP层次

Когда HTTP передает сообщение, оноСодержимое данных сообщения передается в виде一条打开TCP-соединения передаются последовательно. После того, как TCP получает поток данных, переданный ему приложением верхнего уровня, он последовательно разбивает поток данных на сегменты. Затем он передается на уровень IP и передается по сети. С другой стороны, получатели на другом конце собирают полученные сегменты по порядку и передают их протоколу HTTP верхнего уровня для обработки.

tcp http structure

кодирование

Давайте резюмируем:

url стоимость
исходный URL /data?cmd=Fence2Area&meta={"caller":"test","TraceId":"test"}&request={"fence":[{"lng":10.2,"lat":10.2}, {"lng":10.2,"lat":8.2}, {"lng":8.2,"lat":8.2}, {"lng":8.2,"lat":10.2}],"coordtype":2}
закодированный URL /data?cmd=Fence2Area&meta={%22caller%22:%22test%22,%22TraceId%22:%22test%22}&request={%22fence%22:[{%22lng%22:10.2,%22lat%22:10.2},%20{%22lng%22:10.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:8.2},%20{%22lng%22:8.2,%22lat%22:10.2}],%22coordtype%22:2}

В процессе дизассемблирования предыдущего сообщения мы видели гораздо больше%22,фактически,0x22это одинарная кавычка"ASCII-значение ,

С одной стороны, ресурсы, описываемые URL-адресом, могут передаваться через различные другие протоколы, но некоторые протоколы удаляют некоторые определенные символы в процессе передачи; с другой стороны, URL-адрес остается читаемым, поэтому эти непечатаемые символы не могут быть используемые в URL-адресе, например пробелы; наконец, URL-адрес должен быть полным и поддерживать символы на всех языках.

В заключение, дизайнеры URL-адресов интегрируют коды US-ASCII и их escape-последовательности в URL-адреса по ряду причин: с помощью escape-последовательностей произвольные символы или данные могут быть закодированы с помощью ограниченного подмножества набора символов US-ASCII.

Метод выхода: знак процента (%), за которыми следуют два шестнадцатеричных числа, представляющих код ASCII. Например:

转义法

Поэтому неудивительно, что URL-адрес, отправляемый браузером на сервер, закодирован небезопасными символами, верно?

url保留及受限的字符

В URL-адресах кодировка URL-адресов требуется, когда указанные выше зарезервированные символы используются вне зарезервированных целей.

MIME-тип

В данных ответа мы замечаем наличие заголовка:

Content-Type: text/plain; charset=utf-8

В Интернете существуют тысячи различных типов данных, и HTTP помечает каждый объект меткой MIME (многоцелевое расширение Интернет-медиа, многоцелевое расширение электронной почты), которая представляет собой данные ответа.Content-TypeПервоначально MIME использовался в почтовом протоколе, а затем был перенесен на HTTP. Когда браузер получает объект с сервера, он проверяет тип MIME, чтобы знать, как обращаться с этим объектом, отображать ли изображение или вызывать звуковую карту для воспроизведения звука. MIME использует косую черту для определения основного типа объекта и его конкретных подтипов.В следующей таблице показаны некоторые распространенные типы, где тело объекта относится к части тела:

MIME类型

URI/URL/URN

URI (Uniform Resource Identifier, Унифицированный идентификатор ресурса) представляет ресурсы сервера, URL (Унифицированный указатель ресурса, Унифицированный указатель ресурса) и URN (Унифицированное имя ресурса, Унифицированное имя ресурса) — это конкретные реализации URI. URI является общей концепцией и состоит из двух основных подмножеств, URL и URN.URL идентифицирует ресурсы по местоположению, а URN идентифицирует ресурсы по имени.

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

Обычный формат URL:

协议方案+服务器地址+具体的资源路径

Схема протокола (схема), такая какhttp, ftp, который сообщает веб-клиенту, как получить доступ к ресурсу); адрес сервера, напримерwww.oreilly.com; определенные пути к ресурсам, такие какindex.html.

URL举例

HTTP-метод

HTTP поддерживает несколько различных методов запроса, и каждый метод требует различных действий на сервере.На следующем рисунке показано несколько распространенных методов:

常见的http方法

Метод HEAD получает только заголовок, а не часть данных. Такая информация, как тип ресурса (Content-Type) и длина ресурса (Content-Length), может быть получена через заголовок. Таким образом, клиент может получить некоторую информацию о ресурсе, который собирается запросить, и может знать об этом.

POST используется для отправки данных на сервер, обычно отправляя форму; PUT используется для хранения данных в ресурсе на сервере.

код состояния

Каждое ответное HTTP-сообщение будет содержать трехзначный код состояния и поясняющую «фразу-причину», чтобы информировать клиента о статусе запроса и помочь клиенту быстро понять результаты транзакции. Наиболее распространенные из них:

200 OK 
404 Not Found
500 Internal Server Error

Когда мы обычно используем браузер, многие коды ошибок на самом деле обрабатываются браузером, и мы не можем этого воспринять. но404 Not FoundОн проникнет сквозь туман и придет к нам, зачем? Это потому, что он любит нас так сильно!

Клиент может выбрать следующее действие (например, перенаправление и т. д.) в соответствии с этим кодом состояния.

Первая цифра трехзначного числа указывает на классификацию:

http状态分类

формат сообщения

Сообщение HTTP на самом деле состоит из строк строк, и конец каждой строки строк\r\nРазделенные, люди могут легко читать. Кстати, не все протоколы так дружелюбны к человеку, как протокол бережливости, который кидает вам кучу байт и говорит, что0x0001Указывает методы вызова и т. д. Вы можете «декодировать» шестнадцатеричный блок данных только один за другим. Невозможно напрямую кодировать символы, как в протоколе HTTP, чтобы люди могли их напрямую читать.

Вот пример формата простого сообщения запроса и сообщения ответа:

请求响应报文示例

На самом деле сообщение-запрос также может иметь часть body (тело). Сообщение запроса составляется请求行(request line)、请求头部(header)、空行、请求数据Состоит из четырех частей. Единственное, что следует отметить, это то, что даже если основная часть сообщения запроса пуста, после заголовка запроса回车换行Также необходимы символы.

请求报文格式

Формат ответного сообщения аналогичен формату сообщения запроса:

响应报文格式

Сообщение запроса, начальная строка ответного сообщения и поля в заголовке ответа являются текстовыми и структурированными. Тело запроса может содержать любые бинарные данные (например, изображения, видео, программное обеспечение и т. д.), а также, конечно же, текст.

Некоторые заголовки являются общими, а другие доступны только в пакетах запроса или ответа.

столица Атрибуты стоимость имея в виду
Date Универсальный Thu, 03 Jan 2019 12:23:47 GMT время построения сообщения
Accept сообщение запроса text/html,application/xhtml+xml,application/xm Тип данных, которые может получить клиент
Content-Type Универсальный Content-Type: text/plain; charset=utf-8 Тип данных основной части сообщения. Обратите внимание, что если в сообщении запроса также есть часть данных, это поле также является обязательным.

Кстати, если вы используете telnet для прямого подключения к http-порту сервера, команда telnet установит TCP-канал, после чего вы сможете напрямую отправлять данные HTTP-запроса через этот канал и получать данные ответа.

用telnet进行http对话

Расширенный HTTP-протокол

играет роль

Прокси-сервер для HTTP является одновременно веб-сервером и веб-клиентом.

HTTP代理

Использование прокси-сервера дает вам «прикосновение» ко всему проходящему HTTP-трафику, который прокси-сервер может отслеживать и изменять. Обычно некоторый «взрослый» контент фильтруется для детей; сетевые инженеры будут использовать прокси-серверы для повышения безопасности, которые могут ограничивать, через какие данные протокола прикладного уровня могут проходить данные, и фильтровать «вирусы» и другие данные; прокси-серверы могут хранить кэшированные файлы, напрямую вернуться к посетителю, не запрашивая исходные ресурсы сервера; при доступе к общедоступному контенту в медленной сети вы можете притворяться сервером для предоставления услуг по повышению скорости доступа; это называется反向代理; Его можно использовать в качестве маршрутизатора контента, например платных пользователей, он будет направлять запрос к кэш-серверу для повышения скорости доступа; он может преобразовывать язык страницы в соответствии с клиентом, что называется内容转码器; 匿名代理Будет активно удалять информацию, связанную с идентификацией, из HTTP-сообщений, напримерUser-Agent, Cookieи другие поля.

На самом деле запросы к прокси-серверу осуществляются следующими способами:

代理获取流量的方式

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

via字段

Пути передачи сообщений запросов и ответов обычно совпадают, но в противоположных направлениях. Следовательно, порядок промежуточных узлов, указанный полем via в ответном пакете, прямо противоположен.

тайник

Когда есть много запросов на доступ к одной и той же странице, сервер будет передавать одни и те же данные несколько раз, и эти данные многократно передаются в сети, потребляя много пропускной способности. Если эти данные кэшируются, скорость отклика может быть повышена, а пропускная способность сети сохранена.

Большинство кэшей проверяют актуальность реплики только тогда, когда клиент инициирует запрос, а реплика уже устарела. Наиболее распространенные заголовки запросов:If-Modified-Since, Если содержимое не изменится через xx раз (это время является значением If-Modified-Since), сервер ответит304 Not ModifiedВ противном случае сервер нормально отвечает и возвращает исходные данные файла, и этот процесс называется再验证命中.

Повторная проверка может быть удачной или неудачной. При промахе сервер отвечает200 OK, и возвращает полные данные; при попадании сервер отвечает304 Not Modified; В другом случае кеш удаляется, тогда по коду статуса ответа кеш-сервер также удалит свою кешированную копию.

Кстати, если вы хотите использовать кэширование в своем проекте, вы должны обратить внимание на коэффициент попаданий в кэш. Если коэффициент попаданий невысок, необходимо пересмотреть необходимость установки кеша.

Когда кэш-сервер возвращает ответ, он основывается на заголовках кэшированного ответа сервера, а затем выполняет тонкую настройку некоторых полей заголовка. Например, вставив в него информацию о свежести (например,Age, Expiresзаголовок и т. д.) и обычно содержитviaЗаголовок показывает, что кеш предоставляется агентом кеша. Обратите внимание, не изменяйте его в данный момент.Dateполе, представляющее дату, когда исходный сервер изначально создал этот ответ.

HTTP через文档过期机制а также服务器再验证机制Держите кэшированные данные в достаточной степени согласованными с данными между серверами.

Срок действия документа указывает срок действия кэша через следующие поля заголовка:

缓存有效期

Когда время истечения срока действия, подразумеваемое двумя вышеуказанными полями, истекло, актуальность документа необходимо снова проверить на сервере. Если к этому моменту кэш по-прежнему соответствует исходному документу на сервере, кэшу нужно только обновить соответствующие поля в заголовке. как указано в таблице вышеExpiresполя и др.

Чтобы лучше сохранить сетевой трафик, кэш-сервер может отправить его на исходный сервер через соответствующую первую часть.条件GETrequest, так что исходный документ будет возвращен только в том случае, если срок действия кеша действительно истек, иначе будет возвращен только соответствующий заголовок.条件GETВ запросе будут использоваться следующие поля:

缓存条件GET

cookie

Файл cookie — это метка, которую сервер «прикрепляет» к клиенту, часть состояния, поддерживаемая клиентом и отправляемая только обратно на соответствующий сайт.

Существует два типа файлов cookie: файлы cookie сеанса и постоянные файлы cookie. Сеансовые файлы cookie удаляются после выхода из браузера; постоянные файлы cookie сохраняются на жестком диске и сохраняются после перезагрузки компьютера.

Сервер добавляет заголовок поля ответа клиентуSet-cookieилиSet-cookie2, Стоимость名字=值, то есть может содержать несколько полей. В следующий раз, когда браузер снова посетит тот же веб-сайт, он пропустит эти поля черезCookieприносить. Содержимое, сохраняемое в файле cookie, представляет собой идентификатор, который сервер помечает клиентом для облегчения отслеживания службой. Браузеры хранят файлы cookie в определенных файлах в определенных форматах.

Браузер отправит файл cookie только на тот сайт, который его создал.Set-cookieЗначение поля будет содержатьdomainЭто поле сообщает браузеру, что этот файл cookie может быть отправлен на соответствующие соответствующие сайты.pathПоля также являются аналогичными функциями. Например, браузер получает следующие файлы cookie:

Set-cookie: user="mary"; domain="stefno.com"

Затем браузер для доступа к любомуstefno.comВсе сайты в конце отправляют:

Cookie: user="mary"

Сущности и коды

Данные, передаваемые в основной части ответного сообщения, являются бинарными по своей природе. Мы также можем видеть из приведенных выше данных сообщения, что все они представлены шестнадцатеричными числами.Ключ в том, как интерпретировать это содержимое. еслиContent-TypeОпределениеtext/plain, это означает, что содержимое тела является текстом, и мы интерпретируем его непосредственно в соответствии с кодировкой текста; еслиContent-TypeОпределениеimage/png, указывая, что часть тела является изображением, то мы интерпретируем данные в соответствии с форматом изображения.

Content-LengthУказывает длину данных основной части сообщения.Если содержимое сжато, указывает сжатый размер. Кроме того,Content-LengthВ случае длинных соединений несколько пакетов могут быть правильно сегментированы. Следовательно, если блочное кодирование не используется, данные ответа должны включатьContent-Lengthполе. В случае блочного кодирования данные разбиваются на множество небольших блоков, каждый из которых имеет спецификацию размера. Следовательно, любое сообщение с телом (запрос или ответ) должно нести правильныйContent-Lengthстолица.

Ранние версии HTTP разделяли конец сообщения, закрывая соединение. Проблема с этим очевидна: клиент не может сказать, нормально ли завершился сервер или произошел сбой на полпути. Здесь не рекомендуется, если клиент использует close для обозначения конца основной части сообщения запроса, потому что после закрытия невозможно получить ответ сервера. Конечно, клиент может использовать полузакрытый метод только для закрытия направления отправки данных, но многие серверы не распознают его и будут рассматривать полузакрытый метод так, как будто клиент хочет отключиться от сервера.

В процессе передачи HTTP-сообщение может быть непреднамеренно изменено прокси-сервером или другими объектами связи.Чтобы сообщить получателю об этой ситуации, сервер сделает md5 для части тела и поместит значение в полеContent-MD5в этом поле. Однако, если промежуточный агент изменяет тело сообщения и md5, это нелегко обнаружить. Поэтому оговорено, что прокси нельзя модифицироватьContent-MD5первый. Таким образом, после того, как клиент получает данные, он сначала декодирует, затем вычисляет md5 и сравнивает его сContent-MD5сначала для сравнения. В основном это делается для предотвращения непреднамеренных изменений агентом сообщения.

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

编码类型

Конечно, чтобы сервер не возвращал данные, которые не могут быть декодированы клиентом, при запросе он будетAccept-EncodingПриведите поддерживаемый вами метод кодирования в шапку. Если не передается, любая кодировка принимается по умолчанию.

Упомянутое выше кодирование представляет собой кодирование содержимого, при котором кодируются только исходные данные в основной части ответного сообщения и изменяется формат содержимого. Есть другая кодировка:传输编码. Это не имеет ничего общего с содержанием, это изменение способа передачи данных сообщения в сети. Кодирование передачи — это новая функция, представленная в HTTP 1.1.

Обычно серверу необходимо сначала сгенерировать данные, а затем передать их.В это время длина данных может быть рассчитана и закодирована вContent-Lengthсередина. Однако иногда контент генерируется динамически, и сервер хочет начать передачу до того, как данные будут сгенерированы.В настоящее время невозможно узнать размер данных. В этом случае используйте传输编码чтобы отметить конец данных.

Кодирование передачи описывается и контролируется следующими двумя заголовками в протоколе HTTP:

поле имея в виду Типичное значение
Transfer-Encoding Отправитель сообщает получателю, какую кодировку передачи мы сделали фрагментированное кодирование
TE Запрашивающая сторона сообщает серверу, какую кодировку передачи использовать. трейлеры, chunked принимают фрагментированное кодирование и готовы принимать трейлеры в конце сообщения

Формат сообщения с блочным кодированием выглядит следующим образом:

分块编码

Каждый блок содержит значение длины (шестнадцатеричные байты) и данные блока.<CR><LF>Используется для отделения значений длины от данных. Значение длины не содержит<CR><LF>последовательность. Последний блок со значением длины 0 для обозначения конца. Обратите внимание, что заголовок пакета содержитTrailer: Content-MD5, так что сразу после окончания последнего сообщения идет трейлер. Другие, такие как,Content-Length, Trailer, Transfer-EncodingТакже можно использовать как прицеп.

Кодирование контента и кодирование передачи могут использоваться в комбинации.

内容编码和传输编码结合

Международная поддержка

Чтобы поддерживать интернационализированный контент в HTTP, клиент должен сообщить серверу, какой язык он может понять и какой алгоритм кодирования алфавита установлен в браузере. Это проходитAccept-Charsetа такжеAccept-LanguageПервая реализация.

Например:

Accept-Language: fr, en;q=0.8
Accept-Charset: iso-8859-1, utf-8

Указывает: клиент принимает французский (fr, приоритет по умолчанию 1.0), английский (en, приоритет 0.8) и поддерживает кодировку набора символов iso-8859-1, utf-8. Сервер будетContent-Typeпоставить в первыйcharset.

По сути, в теле сообщения HTTP хранится строка двоичных кодов. Сначала мы преобразуем двоичные коды в коды символов (например, ascii — это байт, представляющий символ, а utf-8 означает, что количество байтов символ неопределенный. , каждый символ составляет 1~6 байт), после этого используйте код символа, чтобы найти соответствующий элемент в наборе символов.

Наиболее распространенные наборы символовUS-ASCII: этот набор символов является предком всех наборов символов, и стандарт был выпущен еще в 1968 году. Кодовое значение кода ASCII находится в диапазоне от 0 до 127, и для охвата кодового пространства требуется всего 7 бит. Набор символов, используемый в заголовке HTTP-сообщения и URL-адресе, представляет собой код ASCII. Вы можете посмотреть набор кодов acsii в разделе анализа сообщений выше.

US-ASCIIзаключается в кодировании каждого символа в фиксированное 7-битное двоичное значение.UTF-8Фиксированной схемы кодирования нет. Старший бит первого байта используется для указания количества байтов, используемых закодированным символом (если количество используемых байтов равно 5, первые 5 битов первого байта равны 1, а 6-й бит равен 0). ).Последующие байты содержат 6-битные кодовые значения, используются первые два бита10логотип.

utf-8编码

Например, кодировка Unicode китайского иероглифа «Янь»4E25(100111000100101), всего 15 бит, которые попадают в третью строку в приведенной выше таблице, поэтому для «строгой» кодировки требуется три байта. Буду100111000100101заполните форму вышеcпозиция. Поэтому строгоUTF-8Код — 11100100 10111000 10100101, а преобразование в шестнадцатеричное — E4B8A5. Например, когда я ищу слово «строгий» в окне поиска Google, запрос, отправленный Google, выглядит следующим образом:

https://www.google.com.hk/search?q=%E4%B8%A5&oq=%E4%B8%A5&aqs=chrome..69i57j0l5.3802j0j4&sourceid=chrome&ie=UTF-8&gws_rd=cr

q=%E4%B8%A5Это поисковый запрос.

перенаправление и балансировка нагрузки

Веб-контент часто разбросан по многим местам, что предотвращает «единую точку отказа»: если в одном месте произойдет землетрясение и компьютерный зал будет разрушен, есть другие места, где компьютерный зал может предоставлять услуги. Как правило, будут так называемые «двойные активные», «мультиактивные», так называемые狡兔三窟Хорошо.

Таким образом, запрос пользователя будет负载均衡принцип, по重定向туда, куда он должен идти.

HTTP-перенаправление

После того, как сервер получает запрос клиента, он возвращает код состояния клиенту.302Перенаправленное сообщение, говорящее им, что они должны попробовать что-то еще. Веб-сайт использует перенаправление как простую стратегию балансировки нагрузки,重定向Сервер находит машину с наименьшей доступной нагрузкой, а так как сервер знает адрес клиента, то теоретически может сделать оптимальный выбор перенаправления.

Минусы, конечно, тоже очевидны, так как клиент отправляет два запроса, это увеличивает временные затраты.

перенаправление DNS

DNS связывает несколько IP-адресов с доменом и использует алгоритм для определения возвращаемого IP-адреса. может быть простым轮转; или более продвинутый алгоритм, такой как возврат IP-адреса сервера с наименьшей нагрузкой, который называется负载均衡算法; если учитывается географическое местоположение, адрес, возвращенный в ближайшее местонахождение клиента, называется邻接路由算法; другой — обойти ошибочный адрес, называемый故障屏蔽算法.

DNS-серверы всегда будут возвращать все IP-адреса, но DNS-клиенты, как правило, будут использовать только первый IP-адрес, который будет кэшироваться и всегда будет использоваться после этого. Таким образом, циклический перебор DNS обычно не балансирует нагрузку на отдельных клиентов. Однако, поскольку DNS-сервер всегда возвращает округленный список IP-адресов для разных запросов, нагрузка будет распределяться между несколькими клиентами.

HTTP-соединение

HTTP-соединение является ключевым каналом для передачи HTTP-сообщений.

Параллельное соединение

Когда несколько объектов появляются на странице одновременно, если браузер открывает несколько подключений параллельно и получает эти объекты одновременно, задержки рукопожатия TCP для нескольких подключений могут перекрываться, и скорость будет выше.

Например, на странице, содержащей 3 изображения, браузер должен отправить 4 HTTP-запроса, чтобы получить страницу. 1 для страницы HTML на верхнем уровне и 3 для изображений. Если используется последовательный режим, задержка соединения будет накладываться.

串行连接

После использования параллельных подключений:

并行连接

Тем не менее, параллельные соединения не улучшают скорость абсолютно: если на странице сотни встроенных объектов, необходимо запускать сотни соединений, что также является большой проблемой для производительности сервера. Поэтому обычно браузер ограничивает общий объем данных параллельных соединений небольшим значением, обычно 4, а сервер может закрыть лишние соединения клиента по желанию.

С другой стороны, если пропускная способность клиентской сети мала, каждое соединение будет конкурировать за ограниченную пропускную способность, и каждое соединение получит небольшую скорость, то есть каждый объект будет загружаться с небольшой скоростью. Таким образом, увеличение скорости, вызванное параллельным соединением, будет относительно небольшим или даже не увеличится.

постоянное соединение

Механизм поддержания активности HTTP

Мы знаем, что HTTP-запросы находятся в режиме «запрос-ответ», каждый запрос-ответ должен создавать новое соединение и отключать его после завершения. HTTP не имеет состояния, между соединениями нет связи.

HTTP - это протокол приложений, а TCP - это протокол транспортного уровня. Нижний слой HTTP все еще использует TCP для передачи данных. TCP предоставляет слой надежного канала передачи битов для HTTP. Данные обмененные HTTP, как правило, не велико, и каждое соединение требует трехстороннего рукопожатия с TCP, который потребляет большую часть времени, а иногда даже достигает 50%. Если соединение может быть повторно использовано, задержка, вызванная трехсторонним рукопожатием TCP, может быть уменьшена.

HTTP 1.1 включен по умолчанию механизм поддержки активности, также можно увидеть перехваченные из вышеуказанных пакетов. Таким образом, после завершения передачи данных TCP-соединение должно оставаться постоянно открытым, а затем в рамках одного и того же домена нескольких соединений продолжать использовать этот канал для передачи данных. В ответ на запрос сервера после запроса, это время может оставаться подключенным к тайм-ауту поддержания активности, запрос не в течение этого времени, затем закройте соединение, в противном случае перезапускается обратный отсчет времени до тайм-аута поддержания активности.

http keep alive

HTTP имеет механизм поддержания активности, целью которого является возможность использования TCP Несколько транзакций HTTP передаются по соединению для повышения эффективности связи. Базовый протокол TCP на самом деле также имеет механизм проверки активности, который должен обнаруживать активность соединения TCP. Подтверждение активности уровня TCP может быть установлено на любой стороне, оно может быть установлено на одном конце, одновременно на обоих концах или не на обоих концах. Его необходимо установить при создании нового сокета, чтобы стек протоколов вызывал соответствующую функцию tcp_set_keepalive для активации атрибута поддержания активности соединения.

После установления TCP-соединения на обоих концах сети время простоя (потока данных между двумя сторонами нет) превышаетtcp_keepalive_timeПосле этого ядро ​​сервера попытается отправить клиенту пакет обнаружения для определения статуса TCP-соединения (возможен сбой клиента, принудительное закрытие приложения, недоступен хост и т. д.). Если ответ (подтвержденный пакет) от другой стороны не получен,tcp_keepalive_intvlЗатем попробуйте снова отправить пакет обнаружения, пока не будет получено подтверждение от другой стороны.Если подтверждение от другой стороны не было получено, он будет пытаться выполнить tcp_keepalive_probes всего раз, а интервал между каждым разом составляет 15 с, 30 с, 45 с. , 60-х, 75-х годов. если попробоватьtcp_keepalive_probesЕсли пакет подтверждения от другой стороны по-прежнему не получен, TCP-соединение будет сброшено. Время простоя по умолчанию для TCP-соединений составляет 2 часа, обычно достаточно 30 минут.

Конвейерное соединение

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

В целях безопасности конвейерные соединения подходят только для "идемпотентных" запросов. Обычно мы считаем, что такие методы, как GET/HEAD/PUT/DELETE/TRACE/OPTIONS, являются идемпотентными.

резюме

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

После прочтения статьи мне интересно, улучшилось ли ваше понимание HTTP до более высокого уровня? Добро пожаловать, чтобы общаться и обсуждать вместе.

QR margin2

использованная литература

[HTTP Long Connection]呜呜.cn блог на .com / поколение бесполезной работы / страх / 36 ...

【http/tcp не отключается】сегмент fault.com/ah/119000001…

【http/tcp не отключается】Потяните Ravel-China.org/articles/80…

【tcp поддерживает】blog.51CTO.com/subsystem/1788…

Окончательное руководство [http]book.Douban.com/subject/107…

【Код состояния HTTP】блог woo woo woo.cn на.com/star of/afraid/50…

【Протокол HTTP】Блог Woohoo.cn на.com/ranyonasurus/afraid…

[Классификация состояния HTTP]оооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо.

[кодировка URL]Вууху. Руань Ифэн.com/blog/2010/0…

【http/tcp не отключается】Woohoo.now A magic.net/academy/decent…