我的代碼開始:的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