winsock recv выдает ошибку 10014 - PullRequest
0 голосов
/ 05 ноября 2010

Начну с кода:

typedef std::vector<unsigned char> CharBuf;   
static const int RCV_BUF_SIZE = 1024; 
SOCKET m_socket = a connected and working socket;

// ...

CharBuf buf; // Declare buffer
buf.resize(RCV_BUF_SIZE); // resize buffer to 1024
char* p_buf = reinterpret_cast<char*>(&buf[0]); // change from unsigned char to char
//char p_buf[RCV_BUF_SIZE];

int ret = recv(m_socket, p_buf, RCV_BUF_SIZE, 0); // Does not work

for (int i=0; i<RCV_BUF_SIZE; ++i) // Works (does not crash, so the buffer is ok)
    char c = p_buf[i];

//...

Теперь, когда я запускаю этот код, ret становится равным -1, а WSAGetLastError () возвращает 10014, что означает, что указатель плохой.
Однако я не понимаю, почему это не должно работать? Если я закомментирую строку reinterpret_cast и использую строку ниже, она будет работать!
Можно утверждать, что reinterpret_cast рискованно, но я думаю, что все должно быть в порядке, так как и unsigned char, и подписанный char имеют одинаковый размер. Насколько я знаю, std :: vectors должен быть безопасным для прямого обращения к памяти.

Самое смешное, что когда я делаю то же самое с тем же типом вектора в send (), это работает! Функция отправки:

void SendData(const CharBuf& buf)
{
    buf.resize(RCV_BUF_SIZE); // resize buffer to 1024
    const char* p_buf = reinterpret_cast<const char*>(&buf[0]); // change from unsigned char to char

    int ret = send(m_socket, p_buf, (int)buf.size(), 0); // Works
}

Как мы видим, нет никакой разницы, кроме того, что в этом случае CharBuf является const, может ли это что-то изменить?

Почему recv () более чувствителен, чем send ()? Как recv () может даже знать, что указатель недействителен (что, очевидно, не так) ?? все, что нужно увидеть, это массив символов!

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

bool TcpSocket::ReceiveData(CharBuf* pData)
{
    if (!CheckInitialized("ReceiveData"))
        return false;


    if (m_status != CONNECTED_STAT)
    {
        AddToErrLog("Socket not connected", 1, "ReceiveData");
        return false;
    }

    int ret;
    pData->resize(RCV_BUF_SIZE);
    char* p_buf = reinterpret_cast<char*>(&pData[0]);

    ret = recv(m_socket, p_buf, RCV_BUF_SIZE, 0);

    switch (ret)
    {
    case 0: // Gracefully closed
        AddToLog("Connection gracefully closed", 2);
        Shutdown(); // The connection is closed, no idea to keep running

        return true;

    case SOCKET_ERROR: // Error
        ret = WSAGetLastError();
        if (ret == 10004) // This indicates the socket was closed while we were waiting
            AddToLog("Socket was shut down while waiting for data", 1, "ReceiveData(1)");
        else
            AddToErrLog("Receive data failed with code: " + CStr(ret));

        AddToLog("Connection ended with error", 2);

        Shutdown();
        return false;

    default: // Normal operation
        pData->resize(ret); // Remove unused space

        return true;
    }
}

Неважно. Я нашел это, когда вставлял функцию. Как всегда, вы находите свою ошибку, когда пытаетесь объяснить это кому-то еще :) Я оставляю читателю возможность выяснить, в чем дело, но я дам подсказку & pData [0]. Спасибо за вашу помощь: D

1 Ответ

0 голосов
/ 05 ноября 2010

Нашел ответ сам, вставляя всю функцию, & pData [0] - подсказка.

...