我想在Windows套接字中发送结构。我使用TCP协议。
例如,我有这样的结构:
typedef struct headerLobby
{
unsigned nbGames;
} head;
我发送我的结构:
char buff[DEFAULT_BUFFER_LENGTH]; //DEFAULT_BUFFER_LENGTH = 512
headerLobby header;
header.nbGames = 1;
memcpy(buff, &header, sizeof(headerLobby));
send(ClientSocket, buff, sizeof(headerLobby, 0);
我收到了数据:
headerLobby header;
char recvbuf[DEFAULT_BUFFER_LENGTH];
memset(recvbuf, 0, DEFAULT_BUFFER_LENGTH);
int iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0);
memcpy(&header,recvbuf, sizeof(headerLobby));
但是当我打印header.nbrGames时,我没有很好的价值。
客户端和服务器都在Windows 8 64位和处理器intel x64中。 我不明白我的代码中有什么问题。
答案 0 :(得分:1)
您可以转储您尝试发送的十六进制数据吗?使用wireshark /类似工具在发送/接收端进行数据包捕获,并查看您在线路上看到的数据包数据是您所期望的。
几乎没有最佳做法,
始终将您的结构保持为对齐的大小。如有必要,在struct的末尾使用填充。如果不这样做,编译器将自动保持结构大小对齐,这将导致您在线路上发送的数据可能与您尝试发送的数据不匹配。
在线路上发送任何内容之前,请按网络字节顺序保存数据。您可以使用htonl进行转换。它可能不会导致这里的问题,因为arch是相同的,你正在处理数据等。但它可能会导致可移植代码中的问题。
答案 1 :(得分:0)
(...)
header.nbGames = 1;
memcpy(buff, &header, sizeof(struct headerLobby));
send(ClientSocket, buff, sizeof(struct headerLobby), 0);
memset(recvbuf, 0, 20);
int iResult = recv(ConnectSocket, recvbuf, 20, 0);
memcpy(&recvheader, recvbuf, sizeof(struct headerLobby));
printf("%d\n", recvheader.nbGames);
(...)
$ ./out
1
所以,它有效。你的代码是正确的。或者您显然编辑它以将其粘贴到此处,删除有问题的部分。提示:始终创建一个最小的测试用例,证明或反驳您的问题。
答案 2 :(得分:0)
我发现了我的错误。示例代码有效,但我的错误是我想发送几个结构。当我发送结构时,我没有将角色发送到第一个结构。
例如:
char buff[DEFAULT_BUFFER_LENGTH]; //DEFAULT_BUFFER_LENGTH = 512
headerLobby header;
GameInfo info; //other struct
header.nbGames = 1;
info.nbPlayers = 3;
memcpy(buff, &header, sizeof(headerLobby));
buf += sizeof(headerLobby);
memcpy(buf, &info, sizeof(gameInfo));
send(ClientSocket, buff, sizeof(headerLobby, 0); //I lost the pointeur to the first struct
答案 3 :(得分:-1)
虽然可以安全地完成,但是由于多种原因,通过套接字(或使用任何二进制方法)发送结构数据是有风险的。
内在类型的尺寸 可能因机器而异。
发送计算机上 填充 在接收计算机上可能有所不同
发送计算机上的 endian规则 可能与接收计算机上的不同。
如果您首先将数据序列化到缓冲区( credit to this post ),则会解决这些问题。