Seva ya SOCKS5 huandika baiti nne kwa mbalimbali, na mteja hufanya kazi baada ya uandishi huo kuunganishwa. Kuunganisha kunaweza kubadilisha muda, lakini TCP bado haiahidi usomaji mmoja kwa uandishi mmoja.

Mteja anahitaji kichanganuzi cha jibu. Baada ya kuchagua njia na uthibitishaji wowote unaohitajika, jibu la amri ya SOCKS5 huanza na baiti nne: toleo, matokeo, baiti iliyotengwa na aina ya anwani. Urefu uliobaki unategemea aina hiyo ya anwani.

Kichanganuzi cha .NET 7+ kinachohitaji tu kutumia jibu la CONNECT lililofanikiwa kinaweza kutumia:

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);
}

Baiti mbili za mwisho ni mlango uliofungwa. IPv4 inahitaji baiti nne; IPv6 inahitaji kumi na sita; anwani ya kikoa hubeba baiti ya urefu kabla ya jina.

Toa tokeni ya kughairi pamoja na muda uliokusudiwa wa majadiliano. ReadExactlyAsync hushughulikia usomaji mfupi wa mtu mmoja na hutupa hitilafu wakati mtiririko unaisha kabla ya urefu ulioombwa. Ikishindikana, tupa muunganisho ulioshindikana kupitia njia ya usafishaji ya mmiliki wake.

Ikifanikiwa, simama kwenye mpaka wa jibu. Baiti zilizo baada yake ni za itifaki ya lengwa. Usomaji mkubwa wa kukisia lazima uhifadhi baiti za ziada badala ya kutupa mwanzo wa mtiririko wa programu.

Makala zinazohusiana