SOCKS5 сервери төрт байтты өзүнчө жазат, ал эми кардар бул жазуулар бириктирилгенден кийин гана иштейт. Бириктирүү убакытты өзгөртүшү мүмкүн, бирок TCP дагы эле ар бир жазууга бир окууну убада кылбайт.

Кардарга жооп талдоочусу керек. Ыкма тандоодон жана талап кылынган аутентификациядан кийин SOCKS5 буйругунун жообу төрт байт менен башталат: версия, жыйынтык, резервделген байт жана дарек түрү. Калган узундук ошол дарек түрүнө көз каранды.

Жалаң ийгиликтүү CONNECT жообун керектөөчү .NET 7+ талдоочусу төмөнкүнү колдоно алат:

static async Task ReadConnectReply(Stream stream, CancellationToken ct)
{
    byte[] prefix = new byte[4];
    await stream.ReadExactlyAsync(prefix, ct);
    if (prefix[0] != 5 || prefix[2] != 0)
        throw new IOException("Invalid SOCKS5 reply");
    if (prefix[1] != 0)
        throw new IOException($"SOCKS5 request failed: {prefix[1]}");

    int remaining;
    switch (prefix[3])
    {
        case 1: remaining = 4 + 2; break;
        case 4: remaining = 16 + 2; break;
        case 3:
            byte[] length = new byte[1];
            await stream.ReadExactlyAsync(length, ct);
            remaining = length[0] + 2;
            break;
        default:
            throw new IOException("Unknown SOCKS5 address type");
    }
    await stream.ReadExactlyAsync(new byte[remaining], ct);
}

Акыркы эки байт — байланган порт. IPv4 төрт байт талап кылат; IPv6 он алты байт талап кылат; домен дареги атынын алдында узундук байтын алып жүрөт.

Көздөлгөн сүйлөшүү мөөнөтү менен жокко чыгаруу токенин бериңиз. ReadExactlyAsync кыскараак жеке окууларды иштетет жана агым талап кылынган узундукка жетпей бүтсө, бөтөнчө ыргытат. Ийгиликсиз болсо, ийгиликсиз байланышты анын ээсинин тазалоо жолу менен жок кылыңыз.

Ийгиликте жооптун чек арасында токтоңуз. Андан кийинки байттар багыт протоколуна таандык. Чоңураак божомол окуу ашыкча байттарды сакташы керек, колдонмо агымынын башталышын ыргытууга болбойт.

Тектеш макалалар