Güvenilir UDP'ye ihtiyaç duyduğunuzda ne kullanıyorsunuz?


94

Bir TCP bağlantısının potansiyel olarak çok yavaş olduğu ve bir UDP 'bağlantısının' potansiyel olarak çok güvenilmez olduğu bir durumunuz varsa, ne kullanıyorsunuz? Orada çeşitli standart güvenilir UDP protokolleri var, bunlarla ne gibi deneyimleriniz var?

Lütfen yanıt başına bir protokolü tartışın ve başka biri kullandığınız protokolden daha önce bahsetmişse, bunları oylamayı ve gerekirse ayrıntılarını açıklamak için bir yorum kullanmayı düşünün.

Burada, ölçeğin bir ucunda TCP ve diğer ucunda UDP olan çeşitli seçeneklerle ilgileniyorum. Çeşitli güvenilir UDP seçenekleri mevcuttur ve her biri TCP'nin bazı unsurlarını UDP'ye getirir.

Çoğu zaman TCP'nin doğru seçim olduğunu biliyorum, ancak alternatiflerin bir listesine sahip olmak kişinin bu sonuca varmasına yardımcı olmak için genellikle yararlıdır. UDP üzerine inşa edilen Enet, RUDP vb. Şeylerin çeşitli artıları ve eksileri var, bunları kullandınız mı, deneyimleriniz neler?

Şüpheye mahal vermemek için daha fazla bilgi yok, bu varsayımsal bir sorudur ve bir karar vermesi gereken biri için mevcut olan çeşitli seçenekleri ve alternatifleri ayrıntılı olarak açıklayan bir yanıt listesi ortaya çıkarmasını umduğum bir soru.


1
Bu soru konu dışı gibi görünüyor çünkü teknoloji araştırması yapıyor
Dave Hillier

TCP'nin her durumda en iyisi olduğunu düşünenler, lütfen okuyun: en.wikipedia.org/wiki/Bandwidth-delay_product
nullptr


@EugeneBeresovsky SCTP ile ilgili küçük bir araştırma yaptım, SO cevapları da dahil olmak üzere bilgilerin çoğu 2013 ve daha öncesine tarihleniyor. stackoverflow.com/questions/1171555/…
Michael IV

@MichaelIvanov Benimseme gerçekten düşük. Ancak onu veri merkezinizin içinde kullanmayı düşünüyorsanız, anahtarlar ve yönlendiriciler sorunlara neden olmadıkça (ki bu, bir veri merkezinde olmamalıdır) ve işletim sisteminiz olduğu sürece dışarıdan benimsemeyi önemsemezsiniz. ve bağlantı kurduğunuz sorunun yanıtlarından birinde açıklandığı gibi bir sorun olabilecek kütüphane desteği .
Evgeniy Berezovsky

Yanıtlar:


25

Sorunun etki alanıyla ilgili bazı ek bilgiler olmadan bu soruyu yanıtlamak zordur. Örneğin, ne hacimde veri kullanıyorsunuz? Ne sıklıkla? Verinin doğası nedir? (ör. benzersiz mi, tek seferlik veri mi? Yoksa örnek veri akışı mı? vb.) Hangi platform için geliştiriyorsunuz? (örn. masaüstü / sunucu / gömülü) "Çok yavaş" ile ne demek istediğinizi belirlemek için, hangi ağ ortamını kullanıyorsunuz?

Ancak (çok!) Genel terimlerle, göndermeye çalıştığınız veriler hakkında bazı sert varsayımlar yapamazsanız, hız için tcp'yi yenmek için gerçekten çok uğraşmanız gerekeceğini düşünüyorum.

Örneğin, göndermeye çalıştığınız veriler tek bir paketin kaybına tahammül edebileceğiniz şekildeyse (örneğin, örnekleme hızının sinyalin bant genişliğinden birçok kez daha yüksek olduğu düzenli olarak örneklenmiş veriler), o zaman muhtemelen yapabilirsiniz Veri bozulmasını tespit edebilmenizi sağlayarak aktarımın güvenilirliğinden ödün verin (örneğin, iyi bir crc kullanarak)

Ancak tek bir paketin kaybına tahammül edemezseniz, o zaman tcp'nin zaten sahip olduğu güvenilirlik için teknik türlerini tanıtmaya başlamanız gerekecek. Ve makul miktarda çalışma yapmadan, bu unsurları, kendisiyle birlikte gelen tüm doğal hız sorunlarıyla birlikte bir kullanıcı alanı çözümüne dönüştürmeye başladığınızı fark edebilirsiniz.


5
Tamam, soruyu ayarlayacağım. Bir 'TCP kullan' yanıtı yerine, çeşitli güvenilir UDP protokollerinin artıları ve eksileri ile daha çok ilgileniyorum;)
Len Holgate

9
@Andrew - iki durumda TCP'yi yenmek çok KOLAY: (1) uygulamanızın "tüm verilerden, her zaman sırayla, yinelenmelerden, aşırı kuyruğa girmeden" daha hafif güvenilirlik gereksinimleri vardır. Veya (2) çok noktaya yayın kullanıyorsunuz. Güvenilir UDP, çok noktaya yayın ortamları için çok yaygındır.
Tom

4
Ayrıca TCP, bir WAN bağlantısı üzerinden kullanıldığında (uzun mesafeli sorunlar) korkunç bir şekilde zarar görür. Neden, basit. TCP, penceredeki paketlerin onaylanması gereken pencereleri kullanır. ACK protokolleri, hat mesafesinden kaynaklanan gecikme nedeniyle zarar görür. Google: WAN TCP "ışık hızı"
Ajaxx

3
@Ajaxx, bu konuda çok haklısın, ancak TCP / IP bunu son internet erimesi nedeniyle kasıtlı olarak yapıyor. Herhangi bir tıkanıklık kontrolü olmadan yüksek bit hızı protokolü yapıyorsanız, temelde size utanacaksınız. Ağın sahibiyseniz, vahşi olun.
Kevin Nisbet

2
"örnekleme oranının nikist oranından önemli ölçüde yüksek olduğu durumlarda" - örnekleme oranı tanım gereği her zaman nikist oranının iki katıdır.
Steve

27

Peki ya SCTP . IETF tarafından standart bir protokoldür (RFC 4960)

Hız için yardımcı olabilecek yığın oluşturma özelliğine sahiptir.

Güncelleme: TCP ve SCTP arasındaki bir karşılaştırma , iki arayüz kullanılamıyorsa performansların karşılaştırılabilir olduğunu gösterir.

Güncelleme: güzel bir giriş makalesi .


Bu iyi, IP üzerine inşa etmek yerine UDP üzerine inşa edilebilecek şeylerle daha çok ilgileniyorum ama kesinlikle çözüm alanına uyan bir şey.
Len Holgate

SCTP'nin birçok harika özelliği (çoklu ağ bağlantısı gibi) vardır ve kısmi güvenilirlik uzantısı (RFC 3758) ile inanılmaz derecede esnek bir seçenektir. En son linux çekirdek sürümlerine dahildir, ancak Windows için kendi SCTP yığınınızı yüklemeniz gerekir.
Andrew Johnson

6
SCTP, UDP üzerinden tünellenebilir. tools.ietf.org/id/draft-ietf-sigtran-sctptunnel-00.txt
Miles

Teşekkürler Miles, bu kullanışlı bir bağlantı!
Len Holgate

1
Evet ... Ama UDP ile aynı seviyeden ziyade UDP üzerine inşa edilen bir şeyin kullanıcı alanında, en azından Windows'ta uygulanması muhtemelen daha kolay olacaktır ...
Len Holgate

23

ENET - http://enet.bespin.org/

ENET ile güvenilir bir UDP protokolü olarak çalıştım ve sunucularında kullanan bir müşterim için asenkron soket dostu bir sürüm yazdım. Oldukça güzel çalışıyor ancak eşler arası ping'in boşta kalan bağlantılara eklediği ek yükü sevmiyorum; Çok sayıda bağlantınız olduğunda, hepsine düzenli olarak ping atmak çok yoğun bir iştir.

ENET size birden fazla veri 'kanalı' gönderme ve gönderilen verilerin güvenilmez, güvenilir veya sıralı olması için seçenek sunar. Aynı zamanda canlı tutma görevi gören yukarıda bahsedilen eşler arası ping'i de içerir.


14

UDT (UDP tabanlı Veri Transferi) kullanan (bkz. Http://udt.sourceforge.net/ ) bazı savunma endüstrisi müşterilerimiz var ve bundan çok memnunuz. Görüyorum ki bu da dostane bir BSD lisansına sahip.


2
Müşterileriniz ve özellikle savunma sektöründeki kullanım durumlarından bahseder misiniz? Muhtemelen hayır, ama denemeye değer. Aslında bir dosya aktarım uygulamasında UDT hakkındaki fikri üstlerime fırlattım, ancak henüz hiçbir yere gitmedi.
Thomas Owens

10

RUDP - Güvenilir Kullanıcı Datagram Protokolü

Bu şunları sağlar:

  • Alınan paketlerin onaylanması
  • Pencereleme ve tıkanıklık kontrolü
  • Kayıp paketlerin yeniden iletimi
  • Overbuffering (Gerçek zamanlı akıştan daha hızlı)

Canlı tutma açısından ENet'ten biraz daha yapılandırılabilir görünüyor, ancak size bu kadar çok seçenek sunmuyor (yani, tüm veriler güvenilirdir ve yalnızca olması gerektiğine karar verdiğiniz bitler değil sıralanmıştır). Uygulanması oldukça basit görünüyor.


Buna bakıyordum ama çok fazla uygulama görünmüyor. Bir öneriniz mi var?
Nicholas

Hayır, üzgünüm. Sonunda onu kullanmadım ve her zaman sıfırdan bir uygulama yapacaktım.
Len Holgate

9

Diğerlerinin de belirttiği gibi, sorunuz çok geneldir ve bir şeyin TCP'den 'daha hızlı' olup olmadığı, büyük ölçüde uygulamanın türüne bağlıdır.

TCP genellikle bir ana bilgisayardan diğerine güvenilir veri akışı için aldığı kadar hızlıdır. Bununla birlikte, uygulamanız çok sayıda küçük trafik patlaması yapıyorsa ve yanıtları bekliyorsa, UDP gecikmeyi en aza indirmek için daha uygun olabilir.

Kolay bir orta yol var. Nagle'ın algoritması , TCP'nin gönderenin büyük bir veri akışının alıcısını ezmemesini sağlamaya yardımcı olan, tıkanıklığa ve paket kaybına neden olan bir parçasıdır.

Güvenilir, sıralı TCP teslimatına ve ayrıca UDP'nin hızlı yanıtına ihtiyacınız varsa ve büyük veri akışları göndermekten kaynaklanan tıkanıklık konusunda endişelenmenize gerek yoksa, Nagle'ın algoritmasını devre dışı bırakabilirsiniz:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");

Dediğim gibi, ölçeğin bir ucunda TCP'nin ve diğer ucunda UDP olduğunu varsayarsak, orada başka ne var?
Len Holgate

Bilgiçlik taslamak istiyorsanız, tartışılan protokollerin çoğu UDP üzerine inşa edilmiştir.
smo

TCP'nin bir uçta ve UDP'nin diğer ucunda olduğu varsayımı yanlıştır. Örneğin, UDP'nin akış kontrolü yoktur, paketleri çok hızlı bir şekilde gönderebilir ve bunların arasında bir yönlendiricinin hepsini bırakmasına neden olabilirsiniz. Yani ne yapacaksın ? Kayıp paketleri göz ardı etmek mi yoksa yeniden göndermek mi? Bunları yeniden gönderdiğinizde, TCP'yi aşağı yukarı yeniden uygulayacaksınız. Güvenilir iletişim için başka bir seçenek SCTP'dir.
no

1
Hızlı bir yanıt, mutlaka yüksek bir verime eşit değildir.
Matt

1
Katılmıyorum. Nagle, çok sayıda küçük paket içeren TCP tabanlı protokollerde kullanıldığında, bunları bir araya getirecek ve daha büyük paketler oluşturacaktır. Göndermede biraz gecikmeye neden olur, bu nedenle gecikme çok az artabilir. Bununla birlikte, veri aktarımı kapalıyken daha düşük olabilir çünkü daha fazla paket = daha fazla paket başlığı = daha fazla ek yük. Bir LAN üzerine düşen paketler genellikle daha çok giriş tamponlarının doldurulmasıyla ilgilidir. Aynı ana bilgisayara veri gönderen çok sayıda istemciniz varsa, bu sıfır fark yaratabilir. Nagle'ı kapatıp açmanın pratikte bunu etkileyeceğine inanmıyorum.
Matt

8

Yukarıdaki listenin yeterli olmadığına ve KENDİ güvenilir UDP'lerini geliştirmek istediklerine karar veren herkes, çok sayıda karmaşık köşe durumunu ve olası hizmet reddi saldırılarını kapsadığından, Google QUIC spesifikasyonuna kesinlikle bir göz atmalıdır. Henüz bunun bir uygulamasıyla oynamadım ve sunduğu her şeyi istemeyebilir veya buna ihtiyacınız olmayabilir, ancak belge yeni bir "güvenilir" UDP tasarımına başlamadan önce okumaya değer.

QUIC için iyi bir başlangıç ​​noktası burada , Chromium Blog'da.

Mevcut QUIC tasarım belgesi burada bulunabilir .


4

Bir TCP bağlantısının potansiyel olarak çok yavaş olduğu ve bir UDP 'bağlantısının' potansiyel olarak çok güvenilmez olduğu bir durumunuz varsa, ne kullanıyorsunuz? Orada çeşitli standart güvenilir UDP protokolleri var, bunlarla ne gibi deneyimleriniz var?

Cümlenizdeki anahtar kelime "potansiyel olarak" dır. Protokolünüzde güvenilirliğe ihtiyacınız varsa, TCP'nin aslında ihtiyaçlarınız için çok yavaş olduğunu kendi kendinize kanıtlamanız gerektiğini düşünüyorum.

UDP'den güvenilirlik elde etmek istiyorsanız, temelde TCP'nin bazı özelliklerini UDP'nin üzerine yeniden uygulayacaksınız, bu da muhtemelen işleri ilk başta TCP kullanmaktan daha yavaş hale getirecektir.


Evet, Andrew Edgecombe da aynı şeyi söyledi, ama dediğim gibi NE alternatiflerinin artıları ve eksileri ile ilgileniyorum. Bu alternatifler ve bunların artıları ve eksileri listesi olmadan, neyin en iyi olduğuna karar vermek zor.
Len Holgate

Bilinen bir güvenilirlik işlevi göz önüne alındığında, bazen bir UDP akışı, hte OS'de TCP akışını aşmak için elle ayarlanabilir. Nadir de olsa.
Joshua

1
@ 17/26, Len Holgate'e katılıyorum, TCP bazı durumlarda güvenilir UDP'den daha yavaş olacaktır. Yüksek BDP ağı gibi, Çin'den NewYork'a 1 Gbps internet bağlantınız olduğunu varsayalım, TCP'nin neredeyse tüm 1 Gbps hızlarını kullanmak için emeceğinden eminim. TCP, dünyadaki çoğu bağlantı için daha iyidir, ancak Yüksek Bant Genişliği Gecikme Ürününe sahip ağlar için değildir.
nullptr


3

Olabilir RFC 5405 , "Uygulama Tasarımcılar için Unicast UDP Kullanım Yönergeleri" sizin için yararlı olacaktır.


2

Verilerinizi sıkıştırmayı düşündünüz mü?

Yukarıda belirtildiği gibi, sorunun tam olarak doğası hakkında bilgi sahibi değiliz, ancak verileri taşımak için sıkıştırmak yardımcı olabilir.


1
Özellikle modern sıkıştırma kitaplıkları ile. Bazıları bir memcpy kadar hızlıdır. örneğin lz4.
Matt


1

Soruya evrensel bir cevap vermek zordur, ancak en iyi yol muhtemelen "TCP ile UDP arasında" çizgide kalmak yerine yana doğru gitmektir :).

Biraz daha ayrıntılı açıklama:

Bir uygulamanın, ilettiği her veri parçası için bir onay yanıtı alması gerekiyorsa, TCP alabildiği kadar hızlıdır (özellikle mesajlarınız bağlantınız için en uygun MTU'dan çok daha küçükse) ve Gönderdiğiniz anda süresi dolarsa, ham UDP birçok nedenden ötürü en iyi seçimdir, ancak özellikle hız için değil.

Güvenilirlik daha karmaşık bir sorudur, her iki durumda da biraz görecelidir ve her zaman belirli bir uygulamaya bağlıdır. Basit bir örnek olarak, internet kablosunu yönlendiricinizden çıkarırsanız, TCP ile her şeyi güvenilir bir şekilde teslim etmede iyi şanslar. Daha da kötüsü, kodunuzda bununla ilgili bir şey yapmazsanız, işletim sisteminizin bir hata göstermeden önce büyük olasılıkla uygulamanızı birkaç dakikalığına bloke etmesi ve çoğu durumda bu gecikme kabul edilemez olmasıdır.

Dolayısıyla, geleneksel ağ protokolleriyle ilgili soru genellikle hız veya güvenilirlikle ilgili değil, daha çok rahatlıkla ilgilidir. Bu, TCP'nin bazı özelliklerini (otomatik tıkanıklık kontrolü, otomatik iletim birimi boyut ayarı, otomatik yeniden iletim, temel bağlantı yönetimi, ...) elde ederken, kaçırdığı önemli ve faydalı özelliklerden en azından bazılarını (mesaj sınırları - en çok önemli olan, bağlantı kalitesi izleme, bir bağlantı içinde çoklu akışlar, vb.) ve bunu kendiniz uygulamak zorunda kalmamak.

Benim bakış açıma göre SCTP artık en iyi evrensel seçim gibi görünüyor, ancak çok popüler değil ve onu bugünün İnternetinden güvenilir bir şekilde geçirmenin tek gerçekçi yolu hala onu UDP'nin içine almaktır (muhtemelen sctplib kullanarak ). Yine de nispeten basit ve kompakt bir çözümdür ve bazı uygulamalar için yine de kendi başına yeterli olmayabilir.

Daha gelişmiş seçeneklere gelince, bazı projelerde ZeroMQ kullandık ve gayet iyi çalıştı. Bu, sadece bir ağ protokolü değil, çok daha eksiksiz bir çözümdür (aslında mesajları iletmek için TCP, UDP, birkaç yüksek seviye protokolü ve bazı yerel IPC mekanizmalarını destekler). Birkaç sürümden beri, ilk geliştiricisi dikkatini yeni NanoMSG'sine ve şu anda en yeni NNG kitaplıklarına çevirdi . Kapsamlı bir şekilde geliştirilip test edilmedi ve çok popüler değil ama bir gün değişebilir. CPU ek yükünü ve ağ bant genişliği kaybını önemsemiyorsanız, bazı kitaplıklar sizin için çalışabilir. Diğer bazı ağ odaklı mesaj alışverişi kitaplıkları da mevcuttur.


Güzel cevap. Katılıyorum, SCTP iyi bir seçim ve esnek. Bunu sctplib ve WebRTC veri kanalı çalışması için ev yapımı bir uygulama yoluyla kullandım ve bu iyi.
Len Holgate

-2

UDP kullanarak güvenilirliği elde etmenin en iyi yolu, uygulama programının kendisinde güvenilirliği oluşturmaktır (örneğin, onay ve yeniden iletim mekanizmaları ekleyerek)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.