我将从代码开始:
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() 中使用相同的向量类型做同样的事情时,它会起作用!发送功能:
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;
}
}
没关系。我在粘贴函数时发现了它。像往常一样,当你试图为别人解释它时,你会发现你的错误:) 我把它留给读者来找出问题所在,但我会给出 &pData[0] 作为提示。感谢您的帮助:D