c - 带有指针成员的recv数据包

标签 c windows sockets network-programming winsock

当接收传入的消息时,当我的数据包结构中有一个固定大小的数组时,我会收到正确的结果,如下所示

typedef struct inPacket{
    int cmd;
    int seqNo;
    int numbers[100];
} inPacket;

然后我像这样调用recv

char buf[1024];
recv(m_socket, buf, sizeof(buf));

并将 char 数组转换为数据包类型

inPacket* p = (inPacket*)buf;

这工作正常,在转换后我在“数字”字段中有一个完整的整数数组。当传入我想要存储数字的地址时,我无法想象为什么下面的代码不起作用

void func(int* out)
{
    inPacket inpacket;
    inPacket.numbers = out;
    recv(m_socket, (char*)&inpacket, sizeof(inPacket));
}

调用 recv 后,“numbers”数组是一个错误的指针。

传入的数组由调用函数分配

int numbers[10];
func(numbers);

最佳答案

recv 的作用是,它将数据从内部缓冲区复制到您提供的缓冲区中。所以它会覆盖你的结构的内容。您还可以将数组成员更改为其他指针,这是一个禁忌。不仅如此,您尝试将其设置为比现有数组更小的数组,这可能导致recv可能覆盖新数组之外的内存。

你需要做这样的事情:

void func(int* out, int maxnum)
{
    inPacket inpacket;
    recv(m_socket, (char*)&inpacket, sizeof(inPacket));

    memcpy(out, inpacket.numbers, sizeof(int) * maxnum);
}

然后你像这样调用该函数:

int numbers[10];
func(numbers, 10);

编辑:如果需要动态数组,则必须修改对 recv 的调用以及结构:

typedef struct inPacket{
    int cmd;
    int seqNo;
    int numbers[0];
} inPacket;

void func(int* out, int maxnum)
{
    size_t packetSize = sizeof(inPacket) + sizeof(int) * maxnum;
    inPacket *inpacket = malloc(packetSize);

    recv(m_socket, inpacket, packetSize);

    memcpy(out, inpacket->numbers, sizeof(int) * maxnum);

    free(inpacket);
}

关于c - 带有指针成员的recv数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9393548/

相关文章:

c# - 计算在特定用户登录下运行的单个进程的所有实例的最佳方法是什么?

c - 多线程处理http请求时会发生奇怪的事情

java - 为什么使用 Java 套接字永远不会到达输入流的末尾?

C 警告从不兼容的指针类型传递参数 2 of ‘getopt’

c - 从C中的txt文件打印矩阵

c - 如何防止 asprintf 重写堆上的变量?

c++ - 在 Ubuntu 上找不到 TCP_NODELAY

c++ - 我被困在一个关于 32 位机器读写周期的简单作业中

windows - 在 Linux VirtualBox 和 Windows 7 之间设置网络

c - 可以在C中将HANDLE类型的变量与NULL比较吗?