На самом деле, ::ffff:0:e895:3bc7
является «официальной» формой этого адреса. Форма, подобная IPv4 ::ffff:10.200.0.31
(кстати, не тот же адрес), является лишь альтернативным способом ее записи.
Как мы можем конвертировать? Каждая пара шестнадцатеричных цифр соответствует одному байту, а также каждому из .
разделенных десятичных чисел в формате IPv4. В формате IPv6 каждый :
-разделенный блок соответствует 16 битам (2 байта), и одна последовательность "много нулей" на адрес может быть сокращена до ::
.
Таким образом, 0000000000000000FFFF00000100007F
сопоставляется с 0000:0000:0000:0000:FFFF:0000:0100:007F
как полный формат IPv6-адреса.
Если IPv6-адрес является некоторой формой сопоставленного IPv4-адреса, то RFC определяет альтернативный формат в разделе 5. Текстовое представление специальных адресов . Там последние 32 бита (например, последние два блока, последние 4 байта) заменяются десятичной формой, разделенной точками. В нашем случае 0100:007F
имеет байты 0x01, 0x00, 0x00 и 0x7f, что соответствует 1.0.0.127.
Глядя на это, похоже, у вас проблемы с порядком байтов. Формат для IPv4-сопоставленных адресов IPv6 - :0:0:0:0:0:ffff:‹IPv4›
, и в вашем случае это выглядит так, как будто байты внутри каждого 32-битного блока были заменены. Так что на самом деле ваш адрес должен быть 0000:0000:0000:0000:0000:FFFF:7F00:0001
, и это можно записать как als ::ffff:127.0.0.1
, известный адрес локального хоста IPv4, сопоставленный с IPv4.
Поэтому моей первой рекомендацией было бы поменять местами байты из вашего proc / net / tcp6 в правильном порядке, а затем создать из него InetAdress. Может быть, это уже дает адрес в правильном (смешанном) формате. Если нет, вы можете взять 32 младших бита выходных данных отдельно и либо отформатировать их вручную, либо снова использовать API InetAdress, чтобы отформатировать их как IPv4.