[英]How to send a structure containing pointers over Windows winsock send()?
我正在使用Winsock在C ++中創建服務器/客戶端程序。
將SLogin
和Sid
打包到char array
Sid
到buf[0]
, SLogin
到buf[1]
從buf[0]
獲得的Sid
buf[0]
從buf[1]
獲取Slogin
問題。 這是我的代碼:
#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 OK獲取Sid
。
我在SLogin
錯誤:我將memcpy
SLogin
登錄名復制到buf[1]
並從buf中獲取有問題的Slogin
。
您沒有分配足夠的內存。 您的buffer
大小僅為1個char
( sizeof(char)
為1字節),但是您試圖將12個字節塞入其中( sizeof(Sid)
為4字節, sizeof(SLogin)
為8字節)。 即使您分配了足夠的內存,它也仍然無法工作,因為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");
}
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.