Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有指针成员的recv数据包_C_Windows_Sockets_Network Programming_Winsock - Fatal编程技术网

具有指针成员的recv数据包

具有指针成员的recv数据包,c,windows,sockets,network-programming,winsock,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 = (inPacke

当接收到传入的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);

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

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);
然后调用如下函数:

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

那不可能是真正的代码
inPacket.numbers=out
将触发错误。在这种情况下,我不需要在数据包结构中使用固定大小的数字数组吗?@BillWalton更新了我的答案。当函数退出时,我现在得到一个运行时检查失败-变量“inPacket”周围的堆栈已损坏。你能解释一下零尺寸阵列的用途吗?我不太明白这是怎么回事work@BillWalton是的,应该是这样。我又编辑了一次,现在应该可以更好地工作了。Thatks Joachim工作正常,但它在函数内部分配了缓冲区,我想要的是,我不确定是否可能使用作为数据包一部分传入的内存。进行网络通信的函数需要非常快,并让调用函数进行分配。