winsock recv给出10014错误

时间:2010-11-05 16:45:55

标签: c++ vector winsock recv reinterpret-cast

我将从代码开始:

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和signed char的大小完全相同。
据我所知,std :: vectors应该可以安全地直接在内存中进行寻址。

有趣的是,当我在send()中使用相同的vector-type做同样的事情时,它可以工作!发送功能:

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()怎么能知道指针是无效的(显然不是这样)?所有它应该看到的是一个char数组!

根据要求,我的整个接收功能(请记住,我不能拼出其中的所有功能,但我认为它们应该是相当不言自明的。

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;
    }
}

没关系。我在粘贴功能时发现了它。像往常一样,当您尝试为其他人解释时,您会发现错误:) 我把它留给读者来弄清楚出了什么问题,但我会给&amp; pData [0]一个提示。 谢谢你的帮助:D

1 个答案:

答案 0 :(得分:0)

在粘贴整个函数时自己找到答案,&amp; pData [0]是一个提示。