2011-11-13 20 views
7

Etkisi:Ben nasıl ve neden aşağıdaki kod kesimleri çalışmak mantıklı alamıyorum SO_SNDBUF

/* Now lets try to set the send buffer size to 5000 bytes */ 
    size = 5000; 
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int)); 
    if (err != 0) { 
     printf("Unable to set send buffer size, continuing with default size\n"); 
    } 

biz gönderme tamponunun değerini kontrol ederse, gerçekten de doğru 5000 * 2 = 10000 olarak ayarlanır Ancak, gönderme arabelleği boyutundan daha fazlasını göndermeye çalışırsak, tüm bunları gönderir. Örneğin:

n = send(sockfd, buf, 30000, 0); 

    /* Lets check how much us actually sent */ 
    printf("No. of bytes sent is %d\n", n); 

Bu yazdırır 30000

tam olarak bu çalışma yaptı nasıl? Gönderme arabelleği boyutunun 10000 ile sınırlı olmasının bir etkisi yok mu? Olsaydı, tam olarak ne oldu? Bir çeşit parçalanma mı?

GÜNCELLEME: Soket engelleme modunda değilken ne olur? 20000 (10000 x 2) 30000 bayt gönderilmesine neden olur tampon boyutunu değiştirme 16384 bayt gönderecektir neden olur 10000 (5000 x 2)

  • için

    1. değiştirme tampon boyutu: Aşağıdaki çalıştı

      Bir kez daha, neden?

  • cevap

    11

    SO_SNDBUF ayarının etkisi, TCP ve UDP için farklıdır.

    • UDP için bu datagram boyutuna sınırı, yani daha büyük bir şey atılır belirler.
    • TCP için, yalnızca verilen soket için kernel arabelleği boyutunu ayarlar (sayfa yuvarlaklığına ve bir üst sınıra sahip olan bir yuvarlama ile).

    Eğer TCP bahsediyorsun gibi görünüyor beri gözlemlediğiniz efekt modu, böylece çekirdeğin kadar send(2) blok tüm verilerinizi kabul edin ve/veya ağ olabilir engelleme olmak soket ile açıklanabilir verileri eşzamansız olarak ayırıp veriyi ağ kartına aktarır ve böylece arabelleği boşaltır. Ayrıca, TCP bir akış protokolüdür, herhangi bir "ileti" yapısını korumaz. Bir send(2), diğer taraftaki çoklu recv(2) s ve diğer yöne karşılık gelebilir. Bayt akışı olarak davranın.

    +0

    ve soket engelleme modunda değilse ne olur? Aşağıdakileri denedim: 1) Tampon boyutunu 10000 olarak değiştirmek için 16384 bayt neden olur 2) Arabellek boyutunu 20000 olarak değiştirmek için 30000 bayt neden olur Bir kez daha, neden? – Arun

    +0

    @Arun: bu sadece yuvarlanıyor .. bu neden önemli? arabellek * tam * n bayt olduğu gerçeğine güvenmemelisiniz. çekirdek daha fazla tahsis edebilir. –

    +1

    İlk olarak, çekirdek, arabellek boyutunuzu olduğu gibi @yi_H'nin işaret ettiği gibi almaz. Daha sonra, ağ yığını işleminize * uyumsuz olarak * çalışır. Aşağıdakileri deneyin - sokete yazmaya başlayın, ancak * diğer boyutta okuma *.Sonunda kısa bir süre alırsınız (çekirdek daha az bayt kabul eder, sonra verirsiniz) ya da yazamazsınız. –

    4

    SO_SNDBUF soket uygulamasının dahili olarak kullandığı arabelleği yapılandırır. Soketiniz engellenmiyorsa, sadece yapılandırılmış boyuta kadar gönderebilirsiniz, eğer soketiniz bloke olursa çağrı için herhangi bir sınırlama yoktur.

    İlgili konular