Pelayan SOCKS5 menulis empat bait secara berasingan, dan klien hanya berfungsi selepas tulisan itu digabungkan. Menggabungkan boleh mengubah pemasaan, tetapi TCP masih tidak menjanjikan satu bacaan bagi setiap tulisan.

Klien memerlukan penghurai balasan. Selepas pemilihan kaedah dan sebarang pengesahan yang diperlukan, balasan arahan SOCKS5 bermula dengan empat bait: versi, hasil, bait simpanan dan jenis alamat. Panjang selebihnya bergantung pada jenis alamat itu.

Penghurai .NET 7+ yang hanya perlu menggunakan balasan CONNECT yang berjaya boleh menggunakan:

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

Dua bait terakhir ialah port terikat. IPv4 memerlukan empat bait; IPv6 memerlukan enam belas; alamat domain membawa bait panjang sebelum namanya.

Berikan token pembatalan dengan had masa rundingan yang dimaksudkan. ReadExactlyAsync mengendalikan bacaan individu yang lebih pendek dan melontar pengecualian apabila strim tamat sebelum panjang yang diminta. Jika gagal, buang sambungan yang gagal melalui laluan pembersihan pemiliknya.

Jika berjaya, berhenti pada sempadan balasan. Bait selepasnya milik protokol destinasi. Bacaan spekulatif yang lebih besar mesti mengekalkan bait lebihan dan bukannya membuang permulaan strim aplikasi.

Artikel berkaitan