簡體   English   中英

如何通過Windows winsock send()發送包含指針的結構?

[英]How to send a structure containing pointers over Windows winsock send()?

我正在使用Winsock在C ++中創建服務器/客戶端程序。

  • SLoginSid打包到char array

  • Sidbuf[0]SLoginbuf[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]));

使用memcpySid復制到char array buf[0]char buf[1] )並從buf OK獲取Sid

我在SLogin錯誤:我將memcpy SLogin登錄名復制到buf[1]並從buf中獲取有問題的Slogin

您沒有分配足夠的內存。 您的buffer大小僅為1個charsizeof(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM