Witam,
Pisze klienta GG, niestety, mam kilka problemów związanych z wysyłaniem/odbieraniem pakietów, ze specyfikacji protokołu:
"Przy opisie struktur, założono, że char ma rozmiar 1 bajtu, short 2 bajtów, int 4 bajtów, long long 8 bajtów, wszystkie bez znaku. Używając architektur innych niż i386, należy zwrócić szczególną uwagę na rozmiar typów zmiennych i kolejność bajtów. Poza tym, większość dostępnych obecnie kompilatorów domyślnie wyrównuje zmienne do rozmiaru słowa danej architektury, więc należy wyłączyć tą funkcję. W przypadku gcc będzie to attribute ((packed)) zaraz za deklaracją każdej struktury"
Jednakże nie wiem jak to zastosować, próbuje połączyć się z serwerem korzystając z tego kodu:
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <winsock.h>
using namespace std ;
#define GG_SEND_MSG 0x000b
#define GG_LOGIN_HASH_GG32 0x01
#define GG_LOGIN_HASH_SHA1 0x02
struct gg_header
{
int type; /* typ pakietu */
int length; /* długość reszty pakietu */
};
#define GG_WELCOME 0x0001
struct gg_welcome {
gg_header header;
int seed;
};
#define GG_SEND_MSG80 0x002d
struct gg_send_msg80 {
gg_header header;
int recipient; /* numer odbiorcy */
int seq; /* numer sekwencyjny */
int classa; /* klasa wiadomości */
int offset_plain; /* położenie treści czystym tekstem */
int offset_attributes; /* położenie atrybutów */
char html_message[]; /* treść w formacie HTML (zakończona \0) */
char plain_message[]; /* treść czystym tekstem (zakończona \0) */
char attributes[]; /* atrybuty wiadomości */
};
int gg_login_hash(char *password, unsigned int seed)
{
unsigned int x, y, z;
y = seed;
for (x = 0; *password; password++) {
x = (x & 0xffffff00) | *password;
y ^= x;
y += x;
x <<= 8;
y ^= x;
x <<= 8;
y -= x;
x <<= 8;
y ^= x;
z = y & 0x1f;
y = (y << z) | (y >> (32 - z));
}
return y;
}
#define GG_LOGIN80 0x0031
struct gg_login80 {
gg_header header;
int uin; /* numer Gadu-Gadu */
char language[2]; /* język: "pl" */
char hash_type; /* rodzaj funkcji skrótu hasła */
char hash[64]; /* skrót hasła dopełniony \0 */
int status; /* początkowy status połączenia */
int flags; /* flagi (przeznaczenie nieznane) */
int features; /* opcje protokołu (0x00000007)*/
int local_ip; /* lokalny adres połączeń bezpośrednich (nieużywany) */
short local_port; /* lokalny port połączeń bezpośrednich (nieużywany) */
int external_ip; /* zewnętrzny adres (nieużywany) */
short external_port; /* zewnętrzny port (nieużywany) */
char image_size; /* maksymalny rozmiar grafiki w KB */
char unknown2; /* 0x64 */
int version_len; /* długość ciągu z wersją (0x21) */
char version[34]; /* "Gadu-Gadu Client build 8.0.0.7669" (bez \0) */
int description_size; /* rozmiar opisu */
char description[]; /* opis (nie musi wystąpić, bez \0) */
};
#define GG_LOGIN80_OK 0x0035
struct gg_login80_ok {
int unknown1; /* 01 00 00 00 */
};
#define GG_LOGIN_FAILED 0x0009
#define GG_NEW_STATUS80 0x0038
struct gg_new_status80 {
gg_header header;
int status; /* na jaki zmienić? */
int flags; /* flagi (nieznane przeznaczenie) */
int description_size; /* rozmiar opisu */
char description[]; /* opis (nie musi wystąpić, bez \0) */
};
#define GG_LIST_EMPTY 0x0012
struct set_status {
int typ, size, status;
char desc[2000];
};
#define GG_STATUS_AVAIL 0x0002
int sock;
sockaddr_in sin;
int main(void)
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sin.sin_addr.s_addr = inet_addr("91.197.13.69");
sin.sin_family = AF_INET;
sin.sin_port = htons(8074);
if(connect(sock, (sockaddr *)&sin, sizeof(sin))==0)
{
char buffer[64];
gg_welcome welcome;
recv(sock,(char*) &welcome,12,0);
printf("seed: %d\n",welcome.seed);
printf("%d",WSAGetLastError());
gg_login_hash((char*)"paramparam",welcome.seed);
gg_login80 log80;
log80.header.type=0x15;
log80.header.length=sizeof(gg_login80)-8;
log80.uin=6273116;
log80.language[0]='p';
log80.language[1]='l';
log80.hash_type=0x01;;
itoa (gg_login_hash((char*)"minaret",welcome.seed),buffer,10);
memcpy(log80.hash, buffer, sizeof( buffer ) * 64 );
log80.status=0x0002;
log80.flags=0x00000007;
log80.features=0;
log80.local_ip=0;
log80.local_port=0;
log80.external_ip=0;
log80.external_port=0;
log80.image_size=255;
log80.unknown2=0x64;
log80.version_len=0x21;
memcpy(log80.version, "Gadu-Gadu Client build 8.0.0.7669", sizeof( buffer ) * 34 );
log80.description_size=3;
memcpy(log80.description, "aaa", sizeof( buffer ) * 3 );
send(sock,(char*)&log80,sizeof(log80),0);
int loginstatus;
recv(sock,(char*) &loginstatus,4,0);
printf("\n%d",loginstatus);
}
else
{
printf("not connect");
}
printf("%d",WSAGetLastError());
closesocket(sock);
WSACleanup();
system("pause");
return 0;
}
Czy może mi ktoś podpowiedzieć co robię źle, dlaczego nie chce się połączyć z serwerem?