recv数据包与指针成员

时间:2012-02-22 11:02:47

标签: c windows sockets network-programming winsock

当收到传入的msessage时,当我的数据包结构中有一个固定大小的数组时,我会收到正确的结果,就像这样

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);

2 个答案:

答案 0 :(得分:2)

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);
}

答案 1 :(得分:0)

我的猜测是recv获取缓冲区的大小,并尝试填充它。但是指针的大小只是一个int,所以它可能只读取了几个(4?)字节并将它们放入缓冲区。 对于可变大小的套接字消息,通常必须使用一些结构来知道要接收的消息将有多少字节(比如在消息前加上一个int,这是消息其余部分的大小,然后相应地分配缓冲区并调用再次使用新缓冲区重新开始)