получать входящий трафик с сервера - PullRequest
2 голосов
/ 22 ноября 2010

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

#define RCVBUFSIZE 32

void Receive()
{   
    UINT totalBytesRcvd = 0, bytesRcvd = 0;
    char buffer[RCVBUFSIZE];     /* Buffer for string */

    /* Receive up to the buffer size (minus 1 to leave space for 
    a null terminator) bytes from the sender */

    bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0);

    if (bytesRcvd)
    {
        buffer[bytesRcvd] = '\0';
        MessageBox(0, buffer, 0, 0); //some way to display the received buffer
    }
    else if (bytesRcvd == SOCKET_ERROR)
    {
        return;
    }
}

1 Ответ

5 голосов
/ 22 ноября 2010

(1) Ваш буфер на самом деле не выделен, он находится в стеке.Обычно вам не нужно беспокоиться об использовании 32 байтов в стеке.

(2) recv должен блокироваться до тех пор, пока ему не будет что-то получить.Вы можете обойти это, используя неблокирующие сокеты или select.См. здесь для справки.

В частности, вы можете

(2a) Использовать ioctlsocket , чтобы установить сокет в неблокирующий режим.Затем, когда вы звоните read и читать нечего, вы получаете ошибку EWOULDBLOCK.

unsigned long non_blocking = 1;
ioctlsocket (sockClient, FIONBIO, &non_blocking);

Тогда чтение становится

bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0);
if (bytesRcvd == -1) {
    if (WSAGetLastError() == EWOULDBLOCK) {
        // nothing to read now
    } else {
        // an actual error occurred
    }
} else {
    // reading was successful. Call to MsgBox here
}

(2b) илиВы можете позвонить , выбрать , чтобы определить, есть ли данные для чтения, прежде чем на самом деле вызвать read.

struct timeval timeout;
timeout.tv_usec = 0;
timeout.tv_sec = 0;

fd_set r;
FD_ZERO (&r);
FD_SET (sockClient, &r);
switch (select (sockClient + 1, &r, NULL, NULL, &timeout)) {
    case -1:
        // error
        break;
    case 0:
        // nothing to read
        break;
    case 1:
        // you may call read ()
        break;
}
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...