gpt4 book ai didi

c++ - memcpy 中的数据损坏

转载 作者:行者123 更新时间:2023-11-27 23:10:33 25 4
gpt4 key购买 nike

我目前正在开发一个通过 WinSock 使用套接字的项目,遇到了一个特殊问题。在开始解释之前,我会附上代码。

#include "Connection.h"


Connection::Connection(SOCKET sock, int socketType)
: m_sock(sock), m_recvCount(0), m_sendCount(0), m_socketType(socketType)
{
printf("Succesfully created connection\n");
}


Connection::~Connection(void)
{
printf("Closing socket %d", m_sock);
closesocket(m_sock);
}

void Connection::ProcessMessage(const NetMessage *message){
printf("Got network message: type %d, data %s\n", message->type, message->data);
}


bool Connection::ReadSocket(){
// Call this when the socket is ready to read.
// Returns true if the socket should be closed.

// used to store count between the sockets
int count = 0;

if(m_socketType == SOCK_STREAM){
// attempt to read a TCP socket message
// Receive as much data from the client as will fit in the buffer.
count = recv(m_sock, &m_recvBuf[m_recvCount], sizeof(m_recvBuf) - m_recvCount, 0);
}
else if(m_socketType == SOCK_DGRAM){
// attempt to read UDP socket message

// temporarily stores details of the address which sent the message
// since UDP doesn't worry about whether it's connected to the
// sender or not

sockaddr_in fromAddr;
int fromAddrSize = sizeof(fromAddr);

count = recvfrom(m_sock, &m_recvBuf[m_recvCount], sizeof(m_recvBuf) - m_recvCount, 0, (sockaddr*) &fromAddr, &fromAddrSize);
}
else{
printf("Unknown socket type %d\n", m_socketType);
return true;
}


if (count <= 0)
{
printf("Tried to receive on socket %d and got %d bytes\n", m_sock, count);
printf("Client connection closed or broken\n");
return true;
}

// if we get to this point we have essentially received a complete message
// and must process it

printf("Received %d bytes from the client (total %d)\n", count, m_recvCount);
m_recvCount += count;

// Have we received a complete message?
// if so, process it
if (m_recvCount == sizeof NetMessage)
{
ProcessMessage((const NetMessage *) m_recvBuf);
m_recvCount = 0;
}

return false;
}

bool Connection::WriteSocket(){
// Sends the data in the send buffer through the socket

int count;

if(m_socketType == SOCK_STREAM){
// attempt to read TCP socket message
count = send(m_sock, m_sendBuf, m_sendCount, 0);
}
else if(m_socketType == SOCK_DGRAM){
// attempt to read UDP socket message
count = sendto(m_sock, m_sendBuf, m_sendCount, 0, 0, 0);
}
else{
// unhandled type of socket, kill server
printf("Unknown socket type %d", m_socketType);
return true;
}

if (count <= 0)
{
// we have received an error from the socket
printf("Client connection closed or broken\n");
return true;
}

m_sendCount -= count;
printf("Sent %d bytes to the client (%d left)\n", count, m_sendCount);
printf("Data: %s", m_sendBuf);

// Remove the sent data from the start of the buffer.
memmove(m_sendBuf, &m_sendBuf[count], m_sendCount);

return false;
}

bool Connection::WantWrite(){
if(m_sendCount > 0){
return true;
}

return false;
}

bool Connection::WantRead(){
return true;
}

bool Connection::SetMessage(const NetMessage *message){
// store contents of the message in the send buffer
// to allow us to send later
if (m_sendCount + sizeof(NetMessage) > sizeof(m_sendBuf))
{
return true;
}

memcpy(&m_sendBuf, message, sizeof(message));
m_sendCount += sizeof(NetMessage);

return false;
}

和协议(protocol)

/* Definitions for the network protocol that the client and server use to communicate */

#ifndef PROTOCOL_H
#define PROTOCOL_H

// Message types.
enum MessageType
{
MT_UNKNOWN = 0,
MT_WELCOME = 1,
MT_KEYPRESS = 2,
MT_CHATMESSAGE = 3
};

// The message structure.
// This is a "plain old data" type, so we can send it over the network.
// (In a real program, we would want this structure to be packed.)
struct NetMessage
{
MessageType type;
char* data;

NetMessage()
: type(MT_UNKNOWN)
{
}
};

#endif

本质上,该协议(protocol)包含客户端和服务器相互发送的消息的定义。我遇到的问题是,在 connection.cpp 的第 132 行 (memcpy) 中,消息在 sendBuf 中变得乱码。

http://imgur.com/MekQfgm,9ShRtHi

上图准确地显示了正在发生的事情。正如 protocol.h 中所述,该结构是一个 POD,因此当我执行 memcpy 时,它应该传输结构中保存的字节数(例如,消息类型应为 1 个字节,后跟 7 或 8 个字节的数据,在示例中)。

任何人都可以阐明这一点吗?这让我发疯。

最佳答案

你写的那行在 32 位系统上会复制 4 个字节 (sizeof(pointer)):

memcpy(&m_sendBuf, message, sizeof(message));

你的意思可能是:

memcpy(&m_sendBuf, message, sizeof(NetMessage));

编辑:

此外,正如评论者所说,您的数据类型不是 POD。它持有一个指针。你转移那个指针。在目标系统上,它将指向 RAM 中的同一个位置,但那里什么也没有。您实际上需要使用数组将您的数据类型设为 POD,或者您需要找到一种方法来传输指向的数据。您可以通过传输类型、长度和字符数来实现这一点。这意味着您的接收者不能依赖固定大小的消息。

关于c++ - memcpy 中的数据损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20630622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com