我的代码开始:的Winsock的recv给10014错误
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有风险,但我认为应该可以,因为无符号字符和有符号字符的大小完全相同。
就我所知,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是常量没有区别,可以在改变什么?
为什么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
操作系统可以告诉你传递了一个错误的指针,并且可以返回EFAULT而不是简单地杀死你的程序。发布您正在使用的确切代码,或最小的测试用例。你有什么好看的。 – Thanatos 2010-11-05 16:51:55
片段看起来不错。所以......在你正在编译的实际代码中,你是否仔细检查过“buf”实际上是否分配了一个缓冲区?你是否检查过是否意外地调用了'buf.reserve()'而不是'buf.resize()'?你是否检查过'p_buf'的值,看它在传递给'recv'之前是否看起来合理? – TheUndeadFish 2010-11-05 17:12:06
如果你检查整个函数,我相信你会发现我犯的错误,指针可以欺骗你有时:) – DaedalusAlpha 2010-11-05 17:15:40