2014-01-20 61 views
0

我使用Winsock在C++中创建服务器/客户端程序。如何通过Windows发送包含指针的结构winsock send()?

  • 包装SLoginSidchar array

  • Sidbuf[0]SLoginbuf[1]

  • Sid从获得buf[0]

问题从buf[1]得到Slogin。 这是我的代码:来自BUF OK

#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复制Sidchar array buf[0]char buf[1]) 并获得Sid

我的错误上SLogin: 我复制与memcpySLogin登录buf[1],并从BUF Slogin有问题的。

+0

请告诉我们的错误。 – noelicus

+0

不要使用结构作为网络协议。您至少引入了六个我在其他地方类似问题中列举的依赖项。以八位字节定义一个应用协议,并为自己写一个库来发送和接收它。 – EJP

回答

0

您没有分配足够的内存。您的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)];