私はコードから始めます:
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;
}
}
どうでも。関数を貼り付けているときに見つけました。いつものように、他の人に説明しようとするとエラーが見つかります :) 何が間違っていたのかを理解するのは読者に任せますが、ヒントとして &pData[0] を示します。助けてくれてありがとう:D