Yazılım & Bilgisayar Mühendisliği
C'yi Low- Seviye Ağlama Protokolü Geliştirme için Nasıl Kullanılır
Table of Contents
Neden C Ağlama Protokolleri için Kullanın?
C, düşük seviyeli ağ protokolleri geliştirme için seçim dili kalır, çünkü en az maliyetle benzersiz bir kombinasyon sunar, doğrudan hafıza erişimi ve iyi hazırlanmış donanım kontrolü sağlar. Özel paket başlıkları için elzemlere ihtiyacınız olduğunda, C'de programlamayı başarırsınız veya çöp toplamalı dillerin otomatikleştirilmesi ve bu kontrolleri yönetebilme yeteneğini sağlar.
Ayrıca, C'nin platformlarında taşınabilirliği – Linux sunucularından mikro kontrollere – bu nedenlerle, C'nin yalnızca tarihsel bir sanat eseri değil; yüksek frekanslı ticaret veya IoT iletişim protokolleri için özel ulaşım katmanlarının uygulanması gibi, C'de protokolleri geliştirmeyi öğrenmek size verir.
Çevrenizi Ayarlayın
C'de düşük seviyeli ağ kodunu oluşturmak ve test etmek için, güvenilir bir derleyici, debugging araçları içeren bir geliştirme ortamına ihtiyacınız var ve üretim sistemlerini bozmadan ağ davranışını test etmenin bir yolu.
- [FONT=0)Compiler:[Döneticiler:[Döneticiler:0) GCC (GNU Compiler Collection) ve Clang, C11 ve C17 standartlarını destekler ve büyük uyarılar sağlar ve Windows, MinGW veya Cygwin’de önemli ölçüde geliştirebilecek optimize ediciler de benzer yetenekler sağlayabilir.
- [FONTor veya IDE: [DÜDÜSTRİYE] Visual Studio Code with the C/C++ extension, JetBrains CLion, or Emacs gibi basit bir metin editörü. For debugging, GDB veya LLDB'yi entegre etmek.
- [FONT=0)Testing Altyapısı:[Dönetici:0) Fiziksel ağ arayüzleri üzerinde test edebilirsiniz, ancak sanal arayüzleri (örneğin, TUN/TAP) ev sahibinizi etkilemeden ağ ortamlarını daha uygun hale getirmenize yardımcı olur.
- [FONT:0)Packet Analizi:[Dönetici:[Dönetici:0)Wireshark) ham paketlerini görmek ve protokolünizin tel biçimini uygulamak için paha biçilmez.
Çevreniz hazır olduğunda, ağ programlamasının yatakrock ile başlayabilirsiniz: soketler.
Temelleri
CPU programlama, C. A soketi'deki ağ iletişimi için temel soyutlama, iki yönlü iletişim bağlantının bir uç noktasını temsil eder. soket API, bağlantı kurmak, dinlemek, kabul etmek, göndermek ve veri almak için işlevleri sağlar.
Bir Soket Oluşturun
Sistem adı yeni bir soket oluşturur ve bir dosya tanımlayıcı döndürür. Üç argüman alır:
- [FONT:0) Domain[DÜT:1] - protokol ailesi (örneğin, IPv4, 03: 6) için, IPv6 için, [[TEFLT:6) için ham paketler için.
- [FONT:0]type[Dönetici: 0,3|Dönetici ([DÜDÜDÜSÜSÜSÜŞÜN) (İngilizce).
- [FONT:0]protocol[[[Dönem: 1) Sistem uygun protokolü veya belirli bir IPPROTO değerini seçmesine izin vermek için.
int sock = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
if (sock < 0) {
perror("socket");
exit(1);
}
Her zaman geri dönüş değerini kontrol edin; birçok ağ operasyonu kaynak sınırları veya izinler nedeniyle başarısız olur (kesitler genellikle kök gerektirir).
Binding ve Dinleyin
Bir sunucu soketi için, yerel bir adrese ve porta bağlanmak zorundasınız.Bu, soketi bir İLDİ ile bir araya getiren ve IPv4'e ait olan soketi işaretle yapmanız gerekir.
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; // listen on all interfaces
addr.sin_port = htons(8080);
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
close(sock);
exit(1);
}
if (listen(sock, 5) < 0) {
perror("listen");
close(sock);
exit(1);
}
printf("Listening on port 8080\n");
Liman numarasını siparişe teslim etmek için liman numarasını (büyük-endian) çağırın (büyük-endian) 18. çağrıyı yapmamak, böceklerin ortak bir kaynağıdır.
Bağlantıları ve Data Transferlerini Kabul Etmek
TCP için, sunucu bekleme süresinden ilk bağlantıyı çıkarmak için çağrır.ETHFLT:20) Bağlantılı müşteri için yeni bir soket dosyası tanımlayıcı döndürür.You can then use OLFLT:21) ve / )
int client_fd = accept(sock, NULL, NULL);
if (client_fd < 0) {
perror("accept");
continue;
}
char buffer[1024];
int n = recv(client_fd, buffer, sizeof(buffer), 0);
if (n > 0) {
// process message
}
close(client_fd);
UDP (datagram soketi), bağlantıları kabul etmiyorsunuz. yerine, doğrudan verigramları değiştirmek için [[ŞUDP (datagram soketi), doğrudan bağlantılarınızı kabul etmiyorsunuz.
Hata işleme ve Bloklama vs.
Ağ operasyonları birçok nedenden dolayı başarısız olabilir: ağ erişilebilir, bağlantı sıfırlama, zamanout veya kaynak egzozion.Her zaman geri dön değerler ve kullanım kolaylığı için [[FONTD: 15.000|Spektif, soketler bloke edilir - çoklu parmaklama mekanizmaları (örneğin, anket, epoll) işlem tam olarak tamamlanmış olana kadar birçok bağlantıya sahip olacaktır.
derinlemesine bir ders için, danışması:0)Beej'in Ağ Programlama Kılavuzu) için, C soket programlama için en iyi kaynaklardan biri olmaya devam ediyor.
Farklı Ulaşım protokolleri ile çalışmak
TCP ve UDP (veya diğerleri) arasındaki seçim, protokolünizin güvenilirliğine ve geçki gereksinimlerinize bağlıdır. Özel protokolüniz ya da taşıma katmanını tamamen atlamak için ham soket kullanmaya karar verebilir.
TCP (Stream-Oriented, reliable)
TCP güvenilir bir şekilde, yayın yoluyla sipariş edilir.Retransmissions, akış kontrolü ve sıkışıklık kontrolü ile çalışır. Özel protokolünüz garanti edilebilir teslimat ve sipariş teslim (örneğin, dosya transferi, veritabanı replikasyonu), TCP doğal bir temeldir. ancak, TCP, yüksek çözünürlükte veya kasıtlı olarak) ve gecikmeleri güvenilir mekanizmaları nedeniyle de kendinizletir.You must also handle message limits yourself because TCP is a stream protokol - you need a framing mekanizması (e.g., uzun vadeli bir ek veya kasıtlı olarak)
UDP (Datagram-Oriented, Unreliable)
UDP sends independent datagrams with no guarantee of delivery or ordering. It has lower overhead and minimal latency. Use UDP when your protocol can tolerate packet loss or when real-time performance is critical (e.g., VoIP, gaming, DNS). Because UDP preserves message boundaries, framing is simpler, but you may need to implement your own reliability and sequencing atop it (e.g., using sequence numbers and acknowledgments).
Raw Uses
Raw soketleri, IP paketlerini göndermenize ve almanıza izin verir (veya hatta Ethernet çerçeveleri) çekirdek taşıma katmanı olmadan. Bu, kendi TCP, UDP veya özel başlıklarınızı inşa etmenizi sağlar. Raw soketleri güçlü ancak yüksek ayrıcalıklar ve dikkatli bir şekilde işleme gerektirir.
Özel bir Protokolü Tasarlamak
Özel bir protokol inşa ederken, iki iletişim partisinin akış veya verigramları ile nasıl yorumlandığını ve yorumlandığınız bir protokol, değişken uzunlukta veri, hata tespiti ve bir devlet makinesinin konuşmayı takip etmesi için açık mesaj formatları içeriyor.
Mesaj Framing
Framing, bir akış içinde bir mesajın sınırlarını nasıl buluyorsunuz (TCP) veya verigramları (UDP) Common yaklaşımlar:
- [FONT:0]Length ön ek:[Dönder:[Dönder: 1 ) Her mesajı sabit bir tamsayı ile belirt.Bu sağlam ve verimlidir.
- [FONT=0]Delimiterler:[DFLT:1] Mark, bir dizi özel bir mesajla (örneğin, HTTP'de CRLF) mesajın sonunun bulunduğu sürece, veriden kaçındığınız sürece belirsiz olabilir.
- [FONT:0)Doğrulanmış mesajlar:[Dönemli:[Dönemli:0)[Dönlenmiş mesajlar:[Dönemli-size):[Düzen-size mesaj:[Dönemli:0)[Dönemli:[Dönemli)
Uzun süreli bir üst düzey bir üst üste yapı örneği:
#include <stdint.h>
#pragma pack(push, 1)
struct protocol_header {
uint8_t version; // 1 byte
uint8_t msg_type; // 1 byte
uint16_t payload_len; // 2 bytes, network byte order
// payload follows
};
#pragma pack(pop)
[FONTD: 35) ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
Endianness
Ağ siparişi büyük-endian. protokolüniz, tüm multibayt alanları için siparişi açıkça belirtmelidir.UseENFLT:38) (kullanıcıya göre kısa bir süre içinde) [[Geçmişler için) [[Geçmişler için geçerli değildir.
Hata Tespiti ve Checksums
Yolsuzluk tespit etmek için, bir çek veya CRC (Cyclic Redunucy Check) protokol başlığınıza kadar (IP ve TCP tarafından kullanılan İnternet Checksum gibi) kolayca hesaplanabilir, ancak CRC32 uygulama seviyesindeki veriler için bir seçenek olarak da dahil edebilirsiniz.
Devlet Makineleri
Bir protokol, bir dizi devlet tanımlamaktadır (örneğin, IDLE, İZED, WAITING ACK, CLOSING). Devlet makinesi gibi bir anahtar ifade veya işlev tablosunu kullanarak, basit bir C uygulama yeterlidir.
Raw Uses ile Gelişmiş Ağlama
Raw soketleri IP katmanına veya hatta bağlantı katmanına doğrudan erişim sağlar ([[Dönetici üzerinde · 4/01). Bu, bir taşıma protokolü uygulamak için ihtiyacınız olduğunda, IP başlıkları (örneğin, kaynak adresi spoofing for testing), veya ağ tanı araçları oluşturmak gerekir.
Bir Raw Use Oluştur
int rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); // raw IP packets with TCP protocol
// or
int rawsock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); // all Ethernet frames
Raw soketleri genellikle kök ayrıcalıkları gerektirir. Linux'ta, aynı zamanda IP başlığını kendiniz tedarik edeceğiniz çekirdeği anlatmak için ESFLT:44'i kullanabilirsiniz.
Özel Başçılara Yapın
Çiğ soketleri kullanırken, geçerli IP başlıkları oluşturmaktan, anahtar başlıklarını taşımaktan ve ödeme yüklerini ödemekten sorumlusunuz. Örneğin, özel bir TCP segmenti göndermek için, IP kaynağını ve varış portlarını manuel olarak ayarlamanız gerekir, sıra numarası, bayraklar, pencere büyüklüğü ve TCP checksum'u üst üste hesaplamanız gerekir.
Raw soketleri ayrıca paket enjeksiyonu ve ağ ovma için de kullanılır. Size nihai kontrol verir, ancak protokol yığınının derin anlayışını gerektirir.Rezervasyon için ilgili RFCs -)RFC 793 (TCP)).
Test ve Debugging
Ağ protokolü geliştirme, birden fazla makine ve çekirdek yığını arasındaki etkileşim nedeniyle debug için çok zor. Test etmek için sistematik bir yaklaşım önemlidir.
Wireshark
[[Dönetici:0)Wireshark[[Dönetici:0) Direktifleri arayüz seviyesinde yakalar ve bunları birçok bilinen protokole göre kodlar.Özel protokoller için, Lua veya C'de bir Wireshark dissector yazabilirsiniz, protokolünizi otomatik olarak parlatabilirsiniz.
GDB ile Debugging
GDB (GNU Debugger) sadece bir koşu sunucusu sürecine bağlanabilir, birçok aramanın, DÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNCÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜN
Birim Testi ve Mocking
Protokol mantığı (devlet makineleri, mesaj parsing, çeksum hesaplaması), gerçek ağ arayüzü gerektirmez. Bir çift dosya tanımlayıcısı veya veriyi bir çift dosya tanımlayıcısı aracılığıyla kullanın () örneğin iletişim kurmak için test edebilirsiniz.For example, you can test that send the correct state Transition and that an permissionsum causes return. Tools [...]
Performansı Tahmin Ediyor
Protokolniz yüksek seviyeli veya düşük seviyeli ortamlar için tasarlanmıştırse, performans ayar size optimize araçları verir, ancak onları akıllıca uygulamanız gerekir.
Buffer Boyutları
Her iki soket de gönder ve buffers pencere ölçeğinde ayarlanabilir; beklenen bant genişliğiyle yüz yüze ürünle eşleşmeniz gerekebilir.
I/O ve Multixing
sunucular binlerce bağlantıya sahip olmak için, asla bağlantı başına bir ipi yok. Bunun yerine, etkinlik odaklı I/O. Linux'ta, 03: 5,5|B/macOS, [[BİLMİNCİRESÜŞÜNİVERSİTESİ" nin tüm soket dosya tanımlayıcılarını okumak veya yazmak için hazır olan bu işlemi kayıt altına almak için hazır olan kişiler.
Segmentasyon ve Lock Contention
Protokol uygulamanız birden çok CPU çekirdeğiyle başlanmalıdır, paylaşılan veri yapıları ile dikkatli olun. per-connection tamponları kullanın ve global kilitlerden kaçınmaya çalışın.Spektif ve kullanıcı alanı arasındaki verileri kullanarak üst düzeye çıkar.
Güvenlik Önergeleri
Düşük seviyeli protokol kodu birçok klasik C güvenlik sorunu için savunmasızdır. Çünkü ham bytes ile çalışıyorsunuz, bir hata uzaktan kod yürütmesine veya hizmet inkarına yol açabilir.
Giriş Geçerliliği
Ağdan asla veriye güvenmeyin. Mesajları aldığında, her alan uzunluğu, aralık ve noktalı dengelemeyi kontrol edin.Ücretsiz gerçek tampon boyutunu aşmıyor.
Buffer Overflows'tan Kaçınmak
Basit uzunluk kontrolleri ile sınırlı fonksiyonlar kullanın: ﴾62﴿ ve [[Enable derleyici korumaları (veya daha iyi: 03:64) ve pozisyona bağlı executables için.In variable-long maaş yükleri, tüm hafıza dinamik olarak ancak her zaman kaynak egzozunu önlemek için maksimum boyutunu kaplayın.
Şifreleme
Protokolünüz hassas verileri ele almak zorundaysa, TLS (OpenSSL veya LibreSSL gibi kütüphaneler) kendi kriptonuzu icat etmek yerine, özel şifreleme veya doğrulamayı uygulamanız gerekir, iyi bilinen ilkellere güvenmek (AES-GCM, SHA-256) ve bir güvenlik uzmanına danışın.
Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç
C'deki düşük seviyeli ağ protokolleri geliştirmek, gerekli olduğunda her bir tel üzerinde uyumlu bir kontrol verir.In mastering soket programlama, ulaşım protokol ticaret-offs, doğru endianness ve checksums ile sağlam mesaj formatları tasarlayın ve ham soketleri kullanarak, daha sonra verimli ve güvenilir özel protokolleri oluşturabilirsiniz. Equally important is titiz test with tools like Wireshark and GDB, performans ayarlama I/O and epoll, and always keep security in mind. Start with simple eko servers, thenpriceally add the entire basic testing with the tools.