С++ winsock - recv() возвращает неверный и странный буфер

Я пишу простую игру под названием «Крестики-нолики». Я также хотел создать сетевую функцию с помощью WinSock. В то время как соединение между двумя пользователями проходит без ошибок, я не могу получить корректные данные. После его получения буфер заполняется странными символами типа "☺$0/A" и т.п., а должен получить "Hello!".

Вот мой код:

const char buf[] = "Hello!";
char rbuf[16];
int bytes = 0;
memset(buf, 0, sizeof(buf));

// sending

send(sox, buf, sizeof(buf), 0);

// recv

bytes = recv(sox, rbuf, 16, 0)
rbuf[bytes] = '\0';
cout << rbuf << endl;

person user3366592    schedule 28.02.2014    source источник
comment
Всегда проверяйте возвращаемое значение recv() на наличие ошибок.   -  person Kelm    schedule 01.03.2014
comment
пожалуйста, покажи свой реальный код, он не скомпилируется   -  person 4pie0    schedule 01.03.2014
comment
Похоже, вы правы, потому что он всегда возвращает код SOCKET_ERROR, спасибо за наводку! Я проверю детали позже.   -  person user3366592    schedule 01.03.2014
comment
Всегда проверяйте его и на EOS.   -  person user207421    schedule 01.03.2014


Ответы (1)


Ну, во-первых, вы не проверяете значения return ваших вызовов send/recv, также вы не можете ожидать, что он всегда будет получать 16 байтов. Чтобы убедиться, что вы получите то, что хотите получить, вам, возможно, придется вызвать recv несколько раз. Вот пример решения этой проблемы:

int FixedRecv(SOCKET sox, char* rbuf, int length)
{
    int ref, len = 0;
    do {
        ref = recv(sox, rbuf + len, length - len, 0);

        if(ref == 0) return 0;

        if(SOCKET_ERROR != ref)
            len += ref;
        else return SOCKET_ERROR;
    } while(len < length);

    return len;
}

То же самое относится и к вашим обращениям к send, но я просто хочу, чтобы вы получили общее представление.


Надеюсь, это поможет, используется немного арифметики указателя, но ничего слишком обширного
.

Кроме того, если вы используете неблокирующие сокеты, вам нужно будет проверить WSAEWOULDBLOCK с помощью WSAGetLastError.

person Community    schedule 01.03.2014