简体   繁体   English

如何通过Windows winsock send()发送包含指针的结构?

[英]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 SLoginSid打包到char array

  • Sid to buf[0] and SLogin to buf[1] Sidbuf[0]SLoginbuf[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. 使用memcpySid复制到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个charsizeof(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM