Mae gweinydd SOCKS5 yn ysgrifennu pedwar beit ar wahân, ac mae'r cleient yn gweithio dim ond ar ôl i'r ysgrifiadau hynny gael eu cyfuno. Gall cyfuno newid amseru, ond nid yw TCP yn dal i addo un darlleniad fesul ysgrifiad.

Mae angen parser ateb ar y cleient. Ar ôl dewis dull ac unrhyw ddilysu gofynnol, mae ateb gorchymyn SOCKS5 yn dechrau gyda phedwar beit: fersiwn, canlyniad, beit neilltuedig a math cyfeiriad. Mae'r hyd sy'n weddill yn dibynnu ar y math cyfeiriad hwnnw.

Gall parser .NET 7+ nad oes angen iddo ond bwyta ateb CONNECT llwyddiannus ddefnyddio:

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

Y ddau feit olaf yw'r porthladd rhwym. Mae IPv4 angen pedwar beit; mae IPv6 angen un ar bymtheg; mae cyfeiriad parth yn cario beit hyd o flaen yr enw.

Darperir tocyn canslo gyda'r terfyn amser negodi arfaethedig. Mae ReadExactlyAsync yn trin darlleniadau unigol byrrach ac yn taflu eithriad pan fydd y ffrwd yn gorffen cyn y hyd gofynnol. Ar fethiant, taflwch y cysylltiad methodd drwy lwybr glanhau ei berchennog.

Ar lwyddiant, stopiwch ar ffin yr ateb. Mae beitiau ar ei ôl yn perthyn i brotocol y gyrchfan. Rhaid i ddarlleniad dyfaliadol mwy gadw'r beitiau dros ben yn hytrach na thaflu dechrau ffrwd y cymhwysiad.

Erthyglau cysylltiedig