Özel Protokol Çözümleme
Yerleşik biçimlerin tanıyamadığı özel veya kurum içi bir soket protokolü mü yakaladınız, elinizde bir yığın byte’tan başka bir şey mi kalmadı? Özel çözümleme, kısa bir betikle aracı onu nasıl okuyacağı konusunda eğitmenizi sağlar: sürekli bir byte akışını tek tek mesajlara bölün, protokol başlığını ayıklayın, gerektiğinde sıkıştırmayı açın ve gerisini aracın otomatik yapılandırılmış tanımasına bırakın.
Bu sayfa, kendi çözümleyicisini yazmak isteyenler içindir. Fonksiyonun nasıl yazılacağını, ne zaman çağrıldığını ve dönüş değerinin ne anlama geldiğini açıklar.
1. Ne olduğu: kare başına bir çözümleme kancası
Bölüm başlığı “1. Ne olduğu: kare başına bir çözümleme kancası”Bir çözümleme kancası yazarsınız ve araç, bir bağlantının byte’larını ona besleyip tekrar tekrar aynı soruyu sorar: “Buradan başlayarak, tam bir mesaj kesip çıkarabilir misin?” Bir mesaj kesip çıkarırsınız ve kaç byte kullandığınızı bildirirsiniz; araç kalanla tekrar sorar, akış tamamen dilimlenene kadar bu böyle sürer.
Bir ağ çatısında birikimli bir byte çözümleyici yazdıysanız, zihinsel model aynıdır: sürekli bir byte akışı verildiğinde, mesaj sınırlarına siz karar verirsiniz. İki önemli kural:
- Yönle uğraşmazsınız: bir bağlantının gönderme akışı ve alma akışı, kancanızdan ayrı ayrı geçer ve araç, dilimlenen her mesajı yönüyle otomatik olarak etiketler. Betiğiniz yalnızca “nasıl dilimleneceğiyle” ilgilenir.
- Dilimledikten sonra render işiyle uğraşmazsınız: dışarı ittiğiniz her mesaj yeniden otomatik tanımadan geçer. İçinde protobuf, JSON veya plist varsa, bu daha da ayrıştırılıp yapılandırılmış hale getirilir. Siz yalnızca kareleme, başlık ayıklama ve sıkıştırma açmadan sorumlusunuz.
2. Çözümleme fonksiyonu: decode(buf, out)
Bölüm başlığı “2. Çözümleme fonksiyonu: decode(buf, out)”Çözümleyicinin tamamı tek bir fonksiyondur:
function decode(buf, out) { // buf: şu anda ayrıştırma bekleyen byte akışı; out: çıktı toplayıcı; dönüş: bu seferde tüketilen byte sayısı}Girdilerin, çıktıların ve dönüş değerinin ne olduğu
Bölüm başlığı “Girdilerin, çıktıların ve dönüş değerinin ne olduğu”buf (girdi): ayrıştırma bekleyen byte akışı
- Tür:
ArrayBuffer. İçeriği, “en son tükettiğiniz yerden mevcut sona kadar” kalan tüm byte’lardır. - Özellik
buf.byteLength: şu anda kaç byte kaldığı (her çağrıyla büyüyebilir; bir mesaj dilimlemek için yeterli olup olmadığına bu şekilde karar verirsiniz). - ⚠️ Bu bir ham byte tamponudur,
Uint8Arraydeğildir, dolayısıyla byte’lara doğrudan indeksle erişemezsiniz (buf[0]undefineddöndürür). Byte okumak için 3. bölümdeki yerleşik yardımcıları (u8/u16be/sub…) kullanın veya kendiniz bir görünüm sarın:new Uint8Array(buf),new DataView(buf).
out (çıktı): çıktı toplayıcı
- Tür: düz bir dizi.
- Metot
out.push(mesaj byte'ları): bir mesajı dışarı itin; tek bir çağrıda birden fazlasını itebilirsiniz. - “Mesaj byte’ları” şunlardan biri olabilir: yerleşik bir yardımcının (
sub(...),gunzip(...)gibi) döndürdüğü birArrayBuffer, veya bir string. Diğer türler yok sayılır.
Dönüş değeri: kaç byte tükettiğiniz
- Tür: tam sayı (
number),buf’ın başından kullandığınız byte sayısı. > 0: önden bu kadar byte yediniz ve bir mesaj diliminizi çıkardınız → araç bunları atar ve kalanla sizi tekrar çağırır.0/returnyok / negatif sayı: “önde henüz tam bir mesaj yok” veya “artık dilimlenecek bir şey yok” anlamına gelir → araç döngüyü durdurur ve kalan byte’ları ham olarak gösterir.- Dönüş değeri otomatik olarak tampon uzunluğu içinde sınırlandırılır (taşmaları önlemek için), ancak lütfen gerçekten kullandığınız byte sayısını döndürün.
Ne zaman çağrıldığı (yaşam döngüsü)
Bölüm başlığı “Ne zaman çağrıldığı (yaşam döngüsü)”- Araç, bir bağlantının gönderme akışı üzerinde bir kez, alma akışı üzerinde bir kez geçiş yapar. Her geçişte,
decodedöngü içinde çağrılır: her seferinde size kalan tüketilmemiş byte’lar verilir, bir mesaj dilimler ve tüketilen sayıyı döndürürsünüz, siz 0 döndürene kadar bu böyle sürer. - Bir mesaj yalnızca tüketimi onaylandığında görünür: ittiğiniz mesaj, ancak > 0 döndürdüğünüzde ortaya çıkar. İtip 0 döndürürseniz, döngü durur ve itme iptal edilir, dolayısıyla bir mesaj itmek her zaman kaç byte aldığını döndürmekle eşleştirilmelidir.
- Döngü bittikten sonra, tüketilmemiş sondaki byte’lar kaybolmaz; tek bir ham veri parçası olarak gösterilirler (örneğin, tamamlanmamış bir mesajın ikinci yarısı).
Durum ve idempotanslık
Bölüm başlığı “Durum ve idempotanslık”- Her akış (yön) için ayrı, yepyeni bir betik ortamı oluşturulur; gönderme akışı ve alma akışı birbirine asla karışmaz.
- Çağrılar arasında durumu korumak için (bir sayaç, önceki mesajın türü vb.), değişkenleri
decode’un dışında tanımlayın. Bunlar aynı akış içinde çağrılar arasında kalıcıdır, yön değiştiğinde veya yeniden çözümlediğinizde sıfırlanır. - Çözümleme, zaten yakalanmış veriler üzerinde çalışır ve tekrar tekrar yeniden çalıştırılabilir: betiği düzenleyin, kaydedin ve aynı bağlantıyı yeni kurallarla yeniden çözümlemek için tekrar tıklayın.
Hatalar hiçbir şeyi bozmaz
Bölüm başlığı “Hatalar hiçbir şeyi bozmaz”- Betik bir istisna fırlatırsa veya tek bir çalıştırma zaman aşımına uğrarsa, “bu sefer hiçbir şey tüketilmedi” olarak ele alınır, kalan byte’lar ham veri olarak gösterilir ve yakalama hiç veri kaybı olmadan çalışmaya devam eder.
- Başka bir deyişle, bozuk bir betiğin yapabileceği en kötü şey çözümleyememektir, sizi ham byte’larla bırakır; bağlantıyı çökertmez. Özgürce düzenleyin.
- Ve hatalar yutulmaz: istisnalar ve zaman aşımları, sonuçların üstündeki hata ayıklama çıktısı panelinde gösterilir (bkz. 5. bölüm), gönderme
↑veya alma↓akışından geldiği etiketlenerek. Bunları izleyerek doğrudan düzeltmeye gidin.
3. Yerleşik yardımcılar (betikte doğrudan kullanılabilir)
Bölüm başlığı “3. Yerleşik yardımcılar (betikte doğrudan kullanılabilir)”Yaygın işler, byte okumak, tam sayı okumak, metne dönüştürmek ve sıkıştırmayı açmak, hepsi yerleşiktir, tekerleği yeniden icat etmenize gerek yok:
| Kategori | İmza | Açıklama |
|---|---|---|
| Alt dilim alma | sub(buf, off[, len]) |
off’tan dilimler (sona gitmek için len’i atlayın), ArrayBuffer döndürür |
| Tam sayı okuma | u8(buf, off) / u16be / u16le / u32be / u32le (buf, off) |
Büyük-endian / küçük-endian işaretsiz tam sayılar okur |
| Metne dönüştürme | hex(buf) / ascii(buf) |
Onaltılık dizeye dönüştürür / metin olarak okur |
| Sıkıştırma algılama | gzipMagic(buf) |
gzip olup olmadığı (bir boolean döndürür) |
| Sıkıştırma açma | gunzip / inflate / unzstd / lz4dtx (buf) |
Sıkıştırmayı açar; açamazsa girdi değişmeden döndürülür, hata vermez |
| Hata ayıklama | log(...args) / console.log(...args) |
Hata ayıklama paneline yazdırır (bkz. 5. bölüm) |
Standart byte okuma/yazma yetenekleri (DataView, Uint8Array vb.) da doğrudan kullanılabilir.
4. Örnekler
Bölüm başlığı “4. Örnekler”① Uzunluk öneki [4 byte büyük-endian uzunluk][yük], en yaygın özel protokol şekli:
function decode(buf, out) { if (buf.byteLength < 4) return 0 // uzunluk başlığı tam olarak gelmedi, bekle const total = 4 + u32be(buf, 0) // tüm mesaj = 4 byte'lık başlık + yük if (buf.byteLength < total) return 0 // tüm mesaj tam olarak gelmedi, bekle out.push(sub(buf, 4, total - 4)) // başlığı ayıkla, yükü otomatik tanımaya devret return total // bu mesajı tüket, bir sonrakini dilimlemeye geç}② Ayırıcıya / satıra göre, bir satır sonu gibi bir işaretçide kareleri dilimleme:
function decode(buf, out) { const i = ascii(buf).indexOf('\n') if (i < 0) return 0 // henüz satır sonu yok, bekle out.push(sub(buf, 0, i)) // bu satırı it (satır sonu olmadan) return i + 1 // satır sonunu da birlikte tüket}③ Tamamını bir kerede işleme, tüm akışı tek bir mesaj olarak ele alma, örneğin tamamını sıkıştırmadan çıkarma:
function decode(buf, out) { out.push(gzipMagic(buf) ? gunzip(buf) : buf) // gzip ise, aç return buf.byteLength // her şeyi tüket, döngü hemen biter}④ Türe göre dağıtma, başlıkta bir tür alanıyla ve türe göre farklı işleme:
function decode(buf, out) { if (buf.byteLength < 4) return 0 const total = 4 + u32be(buf, 0) if (buf.byteLength < total) return 0 const type = u8(buf, 4) // ilk byte mesaj türüdür const body = sub(buf, 5, total - 5) out.push(type === 2 ? gunzip(body) : body) // tür 2 sıkıştırılmıştır return total}Editörde bu kalıpların tümü için hazır şablonlar vardır; birini ekleyin, birkaç sayıyı değiştirin ve çalıştırın.

5. Nasıl kullanılır, nasıl hata ayıklanır
Bölüm başlığı “5. Nasıl kullanılır, nasıl hata ayıklanır”- Yaz ve kaydet: çözümleyici editöründe oluşturun, adlandırın ve kaydedin; başlamak için bir şablon ekleyin, yerleşik fonksiyonlar hızlı bir referansta el altında.
- Uygulama: anlam veremediğiniz bir bağlantı için sağ tıklayıp “Şu şekilde çözümle” → çözümleyiciniz seçin, bağlantının tüm gönderme ve alma trafiği hemen kurallarınıza göre dilimlenip gösterilir.
- Hata ayıklama ve değişkenleri inceleme:
decodeiçinde, herhangi bir değeri yazdırmak içinlog(...)veyaconsole.log(...)kullanın: byte sayıları, tür alanları,hex(sub(buf, 0, 8))ve benzeri. Çıktı, “Şu şekilde çözümle” sonuçlarının üstündeki “Hata ayıklama çıktısı” panelinde görünür, her satır gönderme↑veya alma↓akışından geldiği etiketlenmiş olarak. Betik hataları ve zaman aşımları aynı panelde, yine yönle etiketlenmiş olarak görünür. Bu şekilde yazdırıp konum bulun; kör kör düzenlemekten çok daha hızlıdır.Sandbox’ta tam bir tarayıcı / Node
console’u yoktur; yalnızcaconsole.logve eşdeğerilogbu panele bağlıdır.TextDecoder,fetch,setTimeoutve benzerleri kullanılamaz. Byte’ları metin olarak okumak içinascii(buf)kullanın. - Düzenle ve canlı gör: yeniden yakalamaya gerek yok. Betiğinizi kaydedin, “Şu şekilde çözümle”ye tekrar tıklayın, aynı bağlantı yeni kurallarla yerinde yeniden çözümlenir. İstediğiniz şekilde dilimleyene kadar yineleyin.
- Yapıya geçiş: çözümlenen her parça otomatik tanımaya geri verilir, böylece protobuf, JSON ve plist daha da ayrıştırılıp yapılandırılmış hale getirilir; Verileri inceleme ve çözümleme sayfasındaki birden fazla görünüm üzerinden görüntülenebilir.
- Çözümleyiciler adlandırılıp bir liste olarak tutulabilir; istediğiniz zaman eklenebilir, düzenlenebilir veya silinebilir.
6. Ne zaman kullanılır
Bölüm başlığı “6. Ne zaman kullanılır”- Yerleşik biçimlerin tanıyamadığı kurum içi veya özel bir soket protokolü (yaygın bir şekil uzunluk öneki + protobuf / JSON / ikili) yakaladığınızda, dilimlemek ve okunabilir bir yapıya geri döndürmek için bir çözümleyici yazın.
- Özel bir başlıkla sarılmış veya bir tur sıkıştırmadan geçmiş bir byte yığınını yeniden okunabilir içeriğe dönüştürmek istediğinizde.
7. API referansı
Bölüm başlığı “7. API referansı”Birleştirilmiş bir hızlı referans: çözümleme giriş noktası, yerleşik yardımcı fonksiyonlar ve çalışma zamanı ortamı. buf alan her fonksiyon, bir ArrayBuffer veya bir string kabul eder.
Çözümleme giriş noktası
Bölüm başlığı “Çözümleme giriş noktası”decode(buf, out) → number| Amaç | Çözümleyicinin tek giriş noktası, uygulanması zorunludur. buf’ın önünden mesajları dilimleyin, out’a push edin ve bu seferde tüketilen byte sayısını döndürün. |
buf |
ArrayBuffer, ayrıştırma bekleyen kalan byte akışı. Uzunluğu için buf.byteLength kullanın; byte’lara indeksle erişemezsiniz, aşağıdaki yardımcıları veya new DataView(buf) / new Uint8Array(buf)’ı kullanın. |
out |
Array, çıktı toplayıcı. out.push(bytes) bir mesajı dışarı iter (bytes bir ArrayBuffer veya string’dir; diğer türler yok sayılır); tek seferde birden fazlasını itebilirsiniz. |
| Dönüş | number, buf’ın önünden tüketilen byte’lar. > 0 devam eder; 0 / negatif / dönüş yok → durur ve kalan byte’lar ham olarak gösterilir. |
| Çağrı kuralı | Bağlantının gönderme akışı ve alma akışı üzerinde bir geçiş çalıştırın; her geçiş, siz 0 döndürene kadar her seferinde kalan tüketilmemiş byte’ları geçirerek tekrar tekrar çağırır. |
Yerleşik yardımcı fonksiyonlar
Bölüm başlığı “Yerleşik yardımcı fonksiyonlar”Alt dilim alma
| İmza | Döndürür | Açıklama |
|---|---|---|
sub(buf, off) |
ArrayBuffer |
off’tan sona dilimler |
sub(buf, off, len) |
ArrayBuffer |
off’tan len byte dilimler; aralık dışı off / len otomatik olarak sınırlandırılır, hata vermez |
Tam sayı okuma (işaretsiz; off aralık dışıysa 0 döndürür)
| İmza | Döndürür | Açıklama |
|---|---|---|
u8(buf, off) |
number |
1 byte okur |
u16be(buf, off) / u16le(buf, off) |
number |
2 byte okur, büyük-endian / küçük-endian |
u32be(buf, off) / u32le(buf, off) |
number |
4 byte okur, büyük-endian / küçük-endian |
Metne dönüştürme
| İmza | Döndürür | Açıklama |
|---|---|---|
hex(buf) |
string |
Küçük harfli onaltılığa dönüştürür |
ascii(buf) |
string |
Metin olarak okur (ASCII / metin içeriği için uygundur) |
Sıkıştırma / sıkıştırma açma (açamazsa girdi değişmeden döndürülür; tek seferlik sıkıştırma açma sınırı yaklaşık 16 MB)
| İmza | Döndürür | Açıklama |
|---|---|---|
gzipMagic(buf) |
boolean |
gzip sihirli numarasıyla başlayıp başlamadığı |
gunzip(buf) |
ArrayBuffer |
gzip sıkıştırma açma |
inflate(buf) |
ArrayBuffer |
zlib / deflate sıkıştırma açma |
unzstd(buf) |
ArrayBuffer |
zstd sıkıştırma açma |
lz4dtx(buf) |
ArrayBuffer |
Blok LZ4 akışı sıkıştırma açma |
Hata ayıklama
| İmza | Döndürür | Açıklama |
|---|---|---|
log(...args) |
(yok) | Argümanları tek bir satırda birleştirip “Hata ayıklama çıktısı” paneline yazdırır; bir ArrayBuffer onaltılık olarak gösterilir |
console.log(...args) |
(yok) | log ile aynı (console.log’a alışkın olanlar için uygun) |
Çalışma zamanı ortamı
Bölüm başlığı “Çalışma zamanı ortamı”- Standart JavaScript:
ArrayBuffer, tipli diziler (Uint8Arrayvb.),DataView,JSON,Math,RegExp,Dategibi yaygın yerleşik nesnelerin hepsi kullanılabilir; daha alt seviye byte okuma/yazmaya ihtiyacınız olduğundanew DataView(buf)/new Uint8Array(buf)el altındadır. - Hata ayıklama:
log(...)/console.log(...)“Hata ayıklama çıktısı” paneline yazdırır; betik hataları ve zaman aşımları da orada, gönderme↑veya alma↓akışından geldiği etiketlenerek yazdırılır. - Sağlanmayan diğer tarayıcı / Node’a özgü yetenekler:
logdışındakiconsolemetotları,TextDecoder/TextEncoder,fetch,setTimeout,requirevb. hepsi kullanılamaz. Byte’ları metin olarak okumak içinascii(buf)kullanın. - Her
decodeçağrısının bir çalışma süresi sınırı vardır: sonsuz bir döngü veya zaman aşımı kesintiye uğratılır ve “hiçbir şey tüketilmedi” olarak ele alınır, dolayısıyla aracı askıda bırakmaz.
Proxy yakalama sayfasına dön · İlgili: Verileri inceleme ve çözümleme · Yerel NIC yakalama