C++

2012-10-20 20 views
10

'da 'MSG_PEEK' ile 'recv' ile sokette kullanılabilen bayt sayısını alın C++, bayttan soket almak için aşağıdaki işleve sahiptir, MSG_PEEK bayrağıyla kullanılabilen bayt sayısını kontrol edebilir. MSG_PEEK ile, 'recv' döndürülen değeri yuvasında uygun bayt sayısı:C++

I ( buffer için bellek ayırmadan) buffer yaratmadan yuvasında uygun bayt sayısını almak gerekir
#include <sys/socket.h> 
ssize_t recv(int socket, void *buffer, size_t length, int flags); 

. Mümkün ve nasıl?

cevap

25

Daha fazla bilgi ioctlsocket(socket,FIONREAD,&bytes_available) ve ioctlsocket(socket,FIONREAD,&bytes_available).

Ancak, işletim sisteminin sizin için ne kadar veri alacağını garanti etmesi gerekmediği konusunda uyarıda bulunun. Bu nedenle, çok fazla veri bekliyorsanız, veriyi okurken ve depolarken daha iyi okumanız daha iyi olacaktır. Bir şeyleri işlemek için gereken her şeye sahip olana kadar kendi tamponunuzda.

Bunu yapmak için normalde ne yapılır, sadece bir seferde parçalarını okumak gibi

char buf[4096]; 
ssize_t bytes_read; 
do { 
    bytes_read = recv(socket, buf, sizeof(buf), 0); 
    if (bytes_read > 0) { 
     /* do something with buf, such as append it to a larger buffer or 
      * process it */ 
    } 
} while (bytes_read > 0); 

Ve sen veri bekleniyor orada oturmak istemiyorum, sen select veya içine bakmak gerekir Verilerin okunmaya hazır olup olmadığını belirlemek için epoll ve soket için hiçbir zaman engellemediğinizden emin olmak istiyorsanız soketler için O_NONBLOCK bayrağı çok kullanışlıdır.

+0

gelen veriyi sokete "devam eden bayt akışı" veya "tcp paketleri dizisi" olmalı? – jondinham

+0

azami bayt sayısıyla (program tarafından idare edilebilir) çift taraflı bir iş yapacaktır, bence biz gerçekten veri ile uğraştığımızda, ikinci kez – jondinham

+1

Doğru okuduk, bu yüzden ilk yöntem tercih edilir, Gbps hızlarında çalışıyorsunuz, daha sonra hiç fark etmeyeceksiniz .. – hexist

1

Windows'da, FIONREAD bayrağındaki ioctlsocket() işlevini kullanarak gerçek baytların kendilerinin okumasına/bakmasına gerek kalmadan soket kaç bayt olduğunu öğrenebilirsiniz. Döndürülen değer, baypas sayısı recv()'un minimum sayısı engellenmeden geri dönebilir. Aslında recv()'u aradığınızda, daha fazla bayt gelmiş olabilir.

+0

centos linux üzerinde çalışırım – jondinham

+2

@PaulDinh Linux ve Unix üzerinde ioctl() ile çalışır. – EJP

+0

Bu cevap yanlış sonuçlandı. Belgede, Windows'da 'FIONREAD''ün engellemeden' ​​recv''de bulunan bayt sayısını * döndürmediğini * açıkça görüyoruz. Windows'ta 'recv', alt katmanlardan (filtreler ve kuyruklar kendi tamponlarıyla) verileri çekebilirken, FIONREAD bunu yapmaz ve yalnızca üst katmanı kontrol eder. Bkz. [Öğe 12] (https://tangentsoft.net/wskfaq/articles/lame-list.html). –