.NET 7+ SOCKS5 જવાબો: આંશિક TCP વાંચન સંભાળવું
સર્વરની TCP લેખન સીમાઓ પર આધાર રાખ્યા વિના SOCKS5 આદેશ જવાબનો નિશ્ચિત ઉપસર્ગ અને ATYP-આધારિત પ્રત્યય વાંચો.
SOCKS5 સર્વર ચાર બાઇટ અલગ રીતે લખે છે, અને ક્લાયન્ટ ફક્ત ત્યારે જ કામ કરે છે જ્યારે એ લેખનો જોડાઈ જાય. જોડવાથી સમય બદલાઈ શકે છે, પરંતુ TCP હજી પણ દરેક લેખન માટે એક વાંચનનું વચન આપતું નથી.
ક્લાયન્ટને જવાબ પાર્સરની જરૂર છે. પદ્ધતિ પસંદગી અને જરૂરી પ્રમાણીકરણ પછી, SOCKS5 આદેશ જવાબ ચાર બાઇટથી શરૂ થાય છે: આવૃત્તિ, પરિણામ, અનામત બાઇટ અને સરનામાનો પ્રકાર. બાકીની લંબાઈ એ સરનામા પ્રકાર પર આધારિત છે.
.NET 7+ પાર્સર જેને ફક્ત સફળ CONNECT જવાબ વાપરવાનો હોય તે આનો ઉપયોગ કરી શકે છે:
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 ટૂંકા વ્યક્તિગત વાંચન સંભાળે છે અને માંગેલી લંબાઈ પહેલાં સ્ટ્રીમ સમાપ્ત થાય તો અપવાદ ફેંકે છે. નિષ્ફળ થાય તો નિષ્ફળ કનેક્શનને તેના માલિકના સફાઈ માર્ગ દ્વારા કાઢી નાખો.
સફળ થાય તો જવાબની સીમા પર અટકો. તેના પછીના બાઇટ લક્ષ્ય પ્રોટોકોલના છે. મોટું અનુમાનિત વાંચન વધારાના બાઇટ સાચવવા જોઈએ, એપ્લિકેશન સ્ટ્રીમની શરૂઆત ફેંકવી નહીં.