ការឆ្លើយតប SOCKS5 ក្នុង .NET 7+៖ ដោះស្រាយការអាន TCP មិនពេញលេញ
អានបុព្វបទថេរនៃការឆ្លើយតបពាក្យបញ្ជា SOCKS5 និងបច្ច័យដែលអាស្រ័យលើ ATYP ដោយមិនពឹងលើព្រំដែននៃការសរសេរ TCP របស់ម៉ាស៊ីនមេ។
ម៉ាស៊ីនមេ SOCKS5 សរសេរ 4 បៃដាច់ដោយឡែក ហើយឧបករណ៍ប្រើប្រាស់ដំណើរការតែបន្ទាប់ពីការសរសេរទាំងនោះត្រូវបានបញ្ចូលគ្នា។ ការបញ្ចូលគ្នាអាចផ្លាស់ប្ដូរពេលវេលា ប៉ុន្តែ TCP នៅតែមិនធានាការអានមួយក្នុងមួយការសរសេរ។
ឧបករណ៍ប្រើប្រាស់ត្រូវការអ្នកវិភាគការឆ្លើយតប។ បន្ទាប់ពីការជ្រើសវិធី និងការផ្ទៀងផ្ទាត់ដែលត្រូវការ ការឆ្លើយតបពាក្យបញ្ជា SOCKS5 ចាប់ផ្ដើមដោយ 4 បៃ៖ កំណែ លទ្ធផល បៃបម្រុង និងប្រភេទអាសយដ្ឋាន។ ប្រវែងនៅសល់អាស្រ័យលើប្រភេទអាសយដ្ឋាននោះ។
អ្នកវិភាគ .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 ត្រូវការ 4 បៃ; IPv6 ត្រូវការ 16 បៃ; អាសយដ្ឋានដែនយកបៃប្រវែងមួយមុនឈ្មោះ។
ផ្ដល់តូកិនបោះបង់ជាមួយកាលកំណត់ចរចាដែលបានបម្រុង។ ReadExactlyAsync ដោះស្រាយការអានបុគ្គលខ្លីជាង ហើយបោះករណីលើកលែងនៅពេលលំហូរបញ្ចប់មុនប្រវែងដែលបានស្នើ។ ប្រសិនបើបរាជ័យ បោះបង់ការតភ្ជាប់ដែលបរាជ័យតាមផ្លូវសម្អាតរបស់ម្ចាស់វា។
ប្រសិនបើជោគជ័យ ឈប់នៅព្រំដែននៃការឆ្លើយតប។ បៃបន្ទាប់ពីនោះជារបស់ពិធីការគោលដៅ។ ការអានប៉ាន់ស្មានធំជាងត្រូវរក្សាបៃលើស ជាជាងបោះបង់ដំបូងនៃលំហូរកម្មវិធី។