SOCKS5 serveri dörd baytı ayrı-ayrı yazır və müştəri yalnız bu yazılar birləşdikdən sonra işləyir. Birləşdirmə vaxtı dəyişə bilər, lakin TCP hələ də hər yazı üçün bir oxunuş vəd etmir.

Müştəriyə cavab analizatoru lazımdır. Metod seçimindən və tələb olunan autentifikasiyadan sonra SOCKS5 əmr cavabı dörd baytla başlayır: versiya, nəticə, ehtiyat bayt və ünvan növü. Qalan uzunluq həmin ünvan növündən asılıdır.

Yalnız uğurlu CONNECT cavabını istehlak etməli olan .NET 7+ analizatoru bunu istifadə edə bilər:

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

Son iki bayt bağlanmış portdur. IPv4 dörd bayt tələb edir; IPv6 on altı tələb edir; domen ünvanı adından əvvəl uzunluq baytı daşıyır.

Nəzərdə tutulan danışıq müddəti üçün ləğv tokeni verin. ReadExactlyAsync daha qısa fərdi oxunuşları idarə edir və axın tələb olunan uzunluqdan əvvəl bitərsə xəta atır. Uğursuzluq halında uğursuz bağlantını sahibinin təmizləmə yolu ilə atın.

Uğur halında cavab sərhədində dayanın. Ondan sonrakı baytlar təyinat protokoluna aiddir. Daha böyük ehtimal oxunuşu artıq baytları qorumalıdır, tətbiq axınının başlanğıcını atmalı deyil.

Əlaqəli məqalələr