我正在使用Winsock在C ++中创建服务器/客户端程序。
将SLogin
和Sid
打包到char array
Sid
至buf[0]
和SLogin
到buf[1]
Sid
来自buf[0]
从Slogin
获取buf[1]
的问题。
这是我的代码:
#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]));
使用memcpy
将Sid
复制到char array buf[0]
,(char buf[1]
)
并从buf获得Sid
。
SLogin
上的错误:
我使用memcpy
SLogin
登录buf[1]
并从buf获取Slogin
但有问题。
答案 0 :(得分:0)
您没有分配足够的内存。您的buffer
大小只有1 char
(sizeof(char)
是1个字节),但您尝试将12个字节填入其中(sizeof(Sid)
为4个字节,{{1是8个字节)。即使您确实分配了足够的内存,它仍然无法工作,因为sizeof(SLogin)
包含指向外部内存的指针,您不会将其序列化为可以安全发送/接收的连续格式。
尝试更像这样的东西:
SLogin
#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");
}