发送向量 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);
第一次提问!
我有一个小型服务器,可以向客户端发送对象向量:
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);