Protokół gg

0

Chciałem napisać aplikację wykorzystującą sieć gg. Korzystam z opisu protokołu http://dev.null.pl/ekg/docs/protocol.html. Mam następujący kod w cpp:

#include <stdio.h>
#include <winsock2.h>

int main () {
    WSAData wsaData;
    struct sockaddr_in sin;
    SOCKET sock;
    struct hostent* host;
    
    if ((WSAStartup(MAKEWORD(2, 0), &wsaData))) {
                                 printf("ERROR! While starting WSAData.");
                                 return 0;
                                 }
    host = gethostbyname("appmsg.gadu-gadu.pl");
    
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = *((unsigned long*) host->h_addr);
    sin.sin_port = htons(80);
    memset(sin.sin_zero, 0, 8);
    
    sock = socket(AF_INET, SOCK_STREAM, 0);
    
    if (sock<0) {
                printf("ERROR! While starting socket.");
                return 0;
                }
    bind(sock, (sockaddr*)&sin, sizeof(sockaddr));
    connect(sock, (struct sockaddr*)&sin, sizeof(sin));
    
    char zapytanie[] = "GET /appsvc/appmsg4.asp?fmnumber=1234567&version=7, 6, 0, 1688&lastmsg=0r\nAccept: image/gif, image/jpeg, image/pjpeg\r\nAccept-Language: pl\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)\r\nPragma: no-cache\r\nHost: appmsg.gadu-gadu.pl\r\n";
    printf("%s\n\n", zapytanie);
    
    char odpowiedz[1024];
    
    recv(sock, odpowiedz, sizeof(odpowiedz), 0);
    
    printf("%s", odpowiedz);
    
    system("pause");
    return 0;
}

,podobny w php:

<?php
$UIN = '1234567';
$VERSION = '7, 6, 0, 1688';
$FORMAT = '';
$MSG = '';

$fp = fsockopen( "appmsg.gadu-gadu.pl", 80, $errno, $errmsg, 3 );

$get = "GET /appsvc/appmsg.asp?fmnumber=$UIN&version=$VERSION&fmt=$FORMAT&lastmsg=$MSG HTTP/1.0rn";

$get .= "Accept: image/gif, image/jpeg, image/pjpeg, ...";

$get .= "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)rn";

$get .= "Pragma: no-cachern";

$get .= "Host: appmsg.gadu-gadu.plrn";

fputs($fp, $get);

$buf = fgets( $fp, 128 );

echo $buf;
?>

I niestety nie otrzymuję wiadomości od serwera (a jeżeli otrzymuję to krzaki). I stąd moje pytanie - czy kod jest błędny, czy zmieniono protokół gg (ew. czy dany są szyfrowane, jeżeli tak to jak je odszyfrować?) ?

0
  1. Nie określiłeś protokołu socketu
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP /*** TUTAJ ***/);
  1. Nie wysyłasz nic do serwera, tylko zaraz po connect chcesz odbierać ?
    connect(sock, (struct sockaddr*)&sin, sizeof(sin));
    char zapytanie[] = ... // po co kopiujesz string?
    char *zapytanie = ...
    send(sock, zapytanie, strlen(zapytanie), 0);
  1. Po kiego bind?

Poza tym pozbądź się spacji w numerze i dopisz wersję protokołu:

	char *zapytanie = "GET /appsvc/appmsg4.asp?"
		"fmnumber=1234567&version=7%206,%200,%201688&lastmsg=0 HTTP/1.0\r\n"
		"Accept-Language: pl\r\n"
		"User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)\r\n"
		"Pragma: no-cache\r\n"
		"Host: appmsg.gadu-gadu.pl\r\n"
		"\r\n";
0

Poprawiony kod:

#include <stdio.h>
#include <winsock2.h>

int main () {
    WSAData wsaData;
    struct sockaddr_in sin;
    SOCKET sock;
    struct hostent* host;
    
    if ((WSAStartup(MAKEWORD(2, 0), &wsaData))) {
                                 printf("ERROR! While starting WSAData.");
                                 return 0;
                                 }
    host = gethostbyname("appmsg.gadu-gadu.pl");
    
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = *((unsigned long*) host->h_addr);
    sin.sin_port = htons(80);
    memset(sin.sin_zero, 0, 8);
    
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    if (sock<0) {
                printf("ERROR! While starting socket.");
                return 0;
                }
   
    connect(sock, (struct sockaddr*)&sin, sizeof(sin));
    
    char *zapytanie = "GET /appsvc/appmsg4.asp?"
                "fmnumber='2248115'&version='7,6,0,1688'&fmt=''&lastmsg=''%20HTTP/1.0\r\n"
                "Accept-Language: pl\r\n"
                "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)\r\n"
                "Pragma: no-cache\r\n"
                "Host: appmsg.gadu-gadu.pl\r\n"
                "\r\n";
    
    send(sock, zapytanie, sizeof(zapytanie), 0);
    
    printf("%s\n\n", zapytanie);
    
    char odpowiedz[1024];
    
    recv(sock, odpowiedz, sizeof(odpowiedz), 0);
    
    printf("%s", odpowiedz);
    
    system("pause");
    return 0;
}

Nadal nie działa, w odpowiedzi dostaję krzaki.

0

Sprawdziłeś ile bajtów się wysłało? i to, że sizeof dla pointera zwraca 4, a dla char[] ilość 'znaków' + 1?
Gdybyś przeniósł zapytanie (w postaci []) poza funkcje, wtedy mógłbyś użyć sizeof, ale odejmij od tego sizeof(char). Zauważ, że ja użyłem strlen.

Spacji w wersji nie miałeś usuwać tylko zmienić na %20, ale może by to przeszło.
Nie dostajesz krzaków tylko piszesz śmieci ze stosu. Chociaż wyzeruj pierwszy bajt bufora zanim odbierzesz dane.

0

<url>send(sock, zapytanie, strlen(zapytanie), 0);</url>
Działa, dziękuję bardzo.

0

a jak potem mam sie potem zalogowac do serwera? jak wyslac całą strukture

struct gg_login70 { 
    int uin;              /* mój numerek */ 
    char hash_type;       /* rodzaj funkcji skrótu hasła */ 
        char hash[64];        /* skrót hasła */ 
        int status;           /* status na dzień dobry */ 
        int version;          /* moja wersja klienta */ 
        char unknown1;        /* 0x00 */ 
        int local_ip;         /* mój adres ip */ 
    short local_port;     /* port, na którym słucham */ 
        int external_ip;      /* zewnętrzny adres ip */ 
        short external_port;  /* zewnętrzny port */ 
    char image_size;      /* maksymalny rozmiar grafiki w KB */ 
        char unknown2;        /* 0xbe */ 
    char description[];   /* opis, nie musi wystąpić */ 
    int time;             /* czas, nie musi wystąpić */ 
};

i skad <ort>wziasc </ort>ten seed

struct gg_welcome { 
    int seed;    /* ziarno */ 
};

1 użytkowników online, w tym zalogowanych: 0, gości: 1