发送向量 Winsock 问题

Sending Vector Winsock Problems

第一次提问!

我有一个小型服务器,可以向客户端发送对象向量:

void sendFoo(vector<Foo> &foo){
    int num = foo.size();
    sSend = accept(sListen, (SOCKADDR*)&addr, &addrLen);

    for(int i = 0; i < num; i++){
        if(sSend == NULL){
            cout << "Not connected" << endl;
        } else {
            //send vector size
            send(sSend, (char*)&num, sizeof(num), NULL);

            //send foo(s)
            send(sSend, (char*)&foo[i], sizeof(foo[i]), NULL);
        }
    }

    closesocket(sSend);            
}

foo class 包含一个 int id 和一个 double transformation[3][4]

我的客户端应用打印出它收到的 ID 和转换:

sRecv = socket(AF_INET, SOCK_STREAM, NULL);

if (connect(sRecv, (SOCKADDR*)&addr, addrLen) != 0) {
    cout << "Not connected to server" << endl;
} else {

    recv(sRecv, (char*)&num, sizeof(num), NULL);

    vector<Foo> foo(num);

    for (int i = 0; i < num; i++){
        recv(sRecv, (char*)&foo[i], sizeof(foo[i]), NULL);

        //prints them out
    }
}

如果我创建 1 个 Foo 并将其发送到客户端正确打印:

Foo ID: 1
Foo Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000

但是当我尝试发送超过一个时,我每隔一个块就会看到内存引用:

Foo ID: 1
Foo 1 Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000

Foo ID: 4
Foo 4 Transformation:
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66

Foo ID: 2
Foo 2 Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000

Foo ID: 4
Foo 4 Transformation:
1.70592e-314 5.29981e-315 5.30499e-315 5.30758e-315
5.31017e-315 5.29981e-315 5.30499e-315 5.30758e-315
5.31017e-315 5.29981e-315 5.30499e-315 5.30758e-315

//etc

[已解决] 我试图多次发送向量的大小,但客户端只设置为接收一次。感谢您的回答!

嗯,我想说调试器将是你最好的朋友。我也有点惊讶接收端给出了你显示的打印输出,也许还有更多未显示的问题。

查看以下行的位置: send(sSend, (char*)&num, sizeof(num), NULL);

并与您收到的地方进行比较: recv(sRecv, (char*)&num, sizeof(num), NULL);

提示,你调用send多于recv

要通过套接字发送 class,您需要在原始内存块中对其进行序列化。你不能直接发送 C++ 对象。

创建一个函数 uint_32_t Foo::exportRaw( void **buffer) ; 为缓冲区分配原始内存,将 class' 成员放入其中,然后 return 分配大小以通过套接字发送它。

不要忘记在发送和无用时释放您的缓冲内存。

这是一个例子:

void *buffer;
uint32_t sizeAlloc;
sizeAlloc = foo[i].exportRaw(&buffer); // serialize object

//send foo(s)
send(sSend, (char*)buffer, sizeAlloc, NULL);
free(buffer);