[英]How to send a structure containing pointers over Windows winsock send()?
I'm creating a server/client program in C++ using Winsock. 我正在使用Winsock在C ++中创建服务器/客户端程序。
pack the SLogin
and Sid
to char array
将
SLogin
和Sid
打包到char array
Sid
to buf[0]
and SLogin
to buf[1]
Sid
到buf[0]
, SLogin
到buf[1]
Sid
to get from buf[0]
从
buf[0]
获得的Sid
buf[0]
Problems in to get Slogin
from buf[1]
. 从
buf[1]
获取Slogin
问题。 This is my code: 这是我的代码:
#include <Winsock2.h>
#include <Windows.h>
#include <stdio.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
struct Sid
{
unsigned int id;
};
struct SLogin
{
char * login;
char * password;
};
struct SloginRet
{
bool OkOrFalse;
};
SOCKET sSocket = INVALID_SOCKET;
void Connect()
{
WSAData data;
if(WSAStartup(MAKEWORD(2,2), &data) != NO_ERROR)
{
printf("WSAStartup: %d\n", WSAGetLastError());
return;
}
sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sSocket == INVALID_SOCKET)
{
printf("socket: %d\n", WSAGetLastError());
return;
}
sockaddr_in service;
memset(&service, 0, sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(5000);
connect(sSocket, (SOCKADDR*)&service, sizeof(service));
Sid idd;
idd.id = 1001;
char buffer[1];
memcpy(&buffer[0], &idd, sizeof(idd));
Sid ida;
memcpy( &ida, &buffer[0], sizeof(int));
printf("%d %d\n", ida.id, sizeof(buffer));
SLogin login;
login.login = "Vitor";
login.password = "123";
memcpy(&buffer[1], &login, sizeof(char));
SLogin *pLogin = (SLogin*)buffer[1];
printf("%s", pLogin->login);
// send(sSocket, buffer,strlen(buffer), 0);
closesocket(sSocket);
WSACleanup();
}
void main()
{
Connect();
system("pause");
}
Server Recv:
recv(socket,buffer,1,0);
char buffer[1]; //receive
Sid id;
memcpy(&id, &buffer[0],sizeof(buffer[0]));
SLogin login;
memcpy(&login, &buffer[1],sizeof(buffer[1]));
Using memcpy
to copy Sid
to char array buf[0]
, ( char buf[1]
) and get Sid
from buf OK. 使用
memcpy
将Sid
复制到char array buf[0]
( char buf[1]
)并从buf OK获取Sid
。
My Error on SLogin
: I copy with memcpy
SLogin
login to buf[1]
and get Slogin
from the buf with problems. 我在
SLogin
错误:我将memcpy
SLogin
登录名复制到buf[1]
并从buf中获取有问题的Slogin
。
You are not allocating enough memory. 您没有分配足够的内存。 Your
buffer
is only 1 char
in size ( sizeof(char)
is 1 byte), but you are trying to stuff 12 bytes into it ( sizeof(Sid)
is 4 bytes, sizeof(SLogin)
is 8 bytes). 您的
buffer
大小仅为1个char
( sizeof(char)
为1字节),但是您试图将12个字节塞入其中( sizeof(Sid)
为4字节, sizeof(SLogin)
为8字节)。 Even if you did allocate enough memory, it still would not work, as SLogin
contains pointers to outside memory, which you are not serializing into a contiguous format that you can send/recv safely. 即使您分配了足够的内存,它也仍然无法工作,因为
SLogin
包含指向外部内存的指针,您没有将其串行化为可以安全发送/接收的连续格式。
Try something more like this instead: 尝试类似这样的方法:
#pragma pack(push, 1)
// or equivilent for your compiler
struct Sid
{
unsigned int id;
};
struct SLogin
{
char login[20];
char password[20];
};
#pragma pack(pop)
// or equivilent for your compiler
#include <Winsock2.h>
#include <Windows.h>
#include <stdio.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
SOCKET sSocket = INVALID_SOCKET;
void Connect()
{
WSAData data;
int err = WSAStartup(MAKEWORD(2,2), &data);
if (err != NO_ERROR)
{
printf("WSAStartup: %d\n", err);
return;
}
sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sSocket == INVALID_SOCKET)
{
printf("socket: %d\n", WSAGetLastError());
return;
}
sockaddr_in service;
memset(&service, 0, sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(5000);
if (connect(sSocket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
{
printf("connect: %d\n", WSAGetLastError());
closesocket(sSocket);
return;
}
char buffer[sizeof(Sid)+sizeof(SLogin)];
Sid *pSid = (Sid*) &buffer[0];
PSid->id = 1001;
printf("%ul\n", pSid->id);
SLogin *pLogin = (SLogin*) &buffer[sizeof(Sid)];
strncpy(pLogin->login, "Vitor", 20);
strncpy(pLogin->password, "123", 20);
printf("%.20s\n", pLogin->login);
//send(sSocket, buffer, sizeof(buffer), 0);
closesocket(sSocket);
WSACleanup();
}
void main()
{
Connect();
system("pause");
}
char buffer[256]; //receive
int numBytes = recv(socket, buffer, sizeof(buffer), 0);
...
Sid *pSid = (Sid*) &buffer[0];
SLogin *pLogin = (SLogin*) &buffer[sizeof(Sid)];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.