Отправка больших данных> 1 МБ через Windows Sockets, а именно с помощью функции отправки - PullRequest
3 голосов
/ 16 февраля 2009

Я ищу, чтобы отправить большое сообщение> 1 МБ через сокеты Windows отправить API. Есть ли эффективный способ сделать это, я не хочу зацикливаться, а затем отправлять данные кусками. Я где-то читал, что вы можете увеличить размер буфера сокета, и это может помочь. Может ли кто-нибудь подробно остановиться на этом. Любая помощь приветствуется

Ответы [ 6 ]

3 голосов
/ 16 февраля 2009

Вы должны, и фактически должны зацикливаться, чтобы отправлять данные кусками.

Как объяснено в сетевом руководстве Биджа:

"send () возвращает количество фактически отправленных байтов - это может быть меньше, чем число, которое вы сказали ему отправлять! Видите, иногда вы говорите ему отправить целую кучу данных, и он просто не может с этим справиться . Он сработает как можно больше данных и позволит вам отправить остальные позже. "

Это означает, что даже если вы установите размер пакета в 1 МБ, функция send () может отправлять не все, и вы будете вынуждены выполнять цикл до тех пор, пока общее количество байтов, отправленных вашими вызовами send (), не составит количество байтов, которые вы пытаетесь отправить. Фактически, чем больше размер пакета, тем больше вероятность того, что send () не отправит все это.

Помимо всего этого, вы не хотите отправлять пакеты размером 1 МБ, потому что если они будут потеряны, вам придется снова передавать весь пакет размером 1 МБ, тогда как, если вы потеряли пакет размером 1 КБ, его повторная передача не имеет большого значения.

Таким образом, вам придется зациклить ваши вызовы send (), а получателю также придется зациклить свои вызовы recv (). Скорее всего, вам понадобится добавить небольшой заголовок к каждому пакету, чтобы сообщить получателю, сколько байтов отправляется, чтобы получатель мог выполнить цикл соответствующее число раз.

Я предлагаю вам взглянуть на руководство по сети Beej для получения более подробной информации о send () и recv () и о том, как решить эту проблему. Его можно найти на http://beej.us/guide/bgnet/output/print/bgnet_USLetter.pdf

1 голос
/ 16 февраля 2009

С чего вы взяли, что отправка кусками неэффективна? В любом случае операционная система, скорее всего, будет разбивать большие вызовы на «отправку» и объединять мелкие.

Аналогичным образом, на принимающей стороне клиент все равно должен выполнять зацикливание, поскольку нет гарантии получения всех данных за один раз.

1 голос
/ 16 февраля 2009

Почему вы не хотите отправить его кусками?

Это способ сделать это в 99% случаев.

0 голосов
/ 19 августа 2011

Если вы все-таки хотите сделать цикл, вы можете использовать этот код C ++:

#define DEFAULT_BUFLEN 1452    
int SendStr(const SOCKET &ConnectSocket, const std::string &str, int strlen){
        char sndbuf[DEFAULT_BUFLEN];
        int sndbuflen = DEFAULT_BUFLEN;
        int iResult;
        int count = 0;
        int len;
        while(count < strlen){
            len = min(strlen-count, sndbuflen);
            //void * memcpy ( void * destination, const void * source, size_t num );
            memcpy(sndbuf,str.data()+count,len);
            // Send a buffer
            iResult = send(ConnectSocket, sndbuf, len, 0);
            // iResult: Bytes sent
            if (iResult == SOCKET_ERROR){
                throw WSAGetLastError();
            }
            else{
                if(iResult > 0){
                    count+=iResult;
                }
                else{
                    break;
                }
            }
        }
        return count;
    }
0 голосов
/ 13 марта 2009

На практике вы можете выделить большой буфер и отправить за один вызов с помощью Winsock. Если вы не работаете с размерами буфера сокетов, буфер все равно будет скопирован в режим ядра для отправки.

Существует теоретическая вероятность того, что он вернется без отправки всего, поэтому вам действительно следует проверить правильность. Однако отправляемые вами куски должны быть большими (64 Кб или приблизительные), чтобы избежать повторных переходов ядра.

0 голосов
/ 16 февраля 2009

Подсистема сокетов Windows не обязана отправлять весь предоставленный вами буфер. Вы не можете форсировать это, поскольку некоторые протоколы сетевого уровня имеют верхний предел размера пакета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...