Wysyłanie wiadomośći GG

0

Ostatnio siedzę nad protokołem gg, zatrzymałem się przy wysyłaniu i odbieraniu wiadomości, wysyłam jakąś wiadomość i odbieram w orginalnym kliencie no ale zamiast tego co wysłałem dochodzi coś dziwnego np XA ĆĄ...

#define GG_SEND_MSG80 0x002d

	struct gg_send_msg80 {
		int recipient;		/* numer odbiorcy */
		int seq;		/* numer sekwencyjny */
		int classs;		/* klasa wiadomoťci */
		int offset_plain;	/* po│o┐enie treťci czystym tekstem */
		int offset_attributes;	/* po│o┐enie atrybutˇw */
		char html_message[200];	/* treťŠ w formacie HTML (zako˝czona \0) */
		char plain_message[200];	/* treťŠ czystym tekstem (zako˝czona \0) */
		char attributes;	/* atrybuty wiadomoťci */
	}mmss;

	mmss.recipient = 2357907;		/* numer odbiorcy */
	mmss.seq=rand() % 65000;		/* numer sekwencyjny */
	//mmss.classs=0x0008;		/* klasa wiadomoťci */
	mmss.classs=0x0020;		/* klasa wiadomoťci */
	mmss.offset_plain=0;	/* po│o┐enie treťci czystym tekstem */
	mmss.offset_attributes=0;	/* po│o┐enie atrybutˇw */
	strcpy(mmss.html_message, "\0");
	strcpy(mmss.plain_message, "elo\0");
	mmss.attributes = 0x00;	/* atrybuty wiadomoťci */
	
	header.type=GG_SEND_MSG80;
	header.length=sizeof(mmss);
	send(sockd, (char*)&header, sizeof(header),0); 

	if(send(sockd, (char*)&mmss, header.length,0 ))
	{
		clear(&header);
		printf("Wyslano\n");
	}

Wydaje mi się że coś jest ze strukturą, źle ją wypełniam albo co... Tylko nie wiem co...

0

A spróbuj te pola ze stringami (html_message, plain_message) wypełnić normalnie, bez \0. Wydaje mi się, że w komentarzu chodziło o to, że tam po prostu ma być ciąg bajtów oznaczający tekst i jeden bajt 0 (znak '\0') na końcu. Ten znak '\0' jest jednak już zawarty w każdym c-stringu. Gdy masz c-string "abc", to są to bajty (chary):

'a'
'b'
'c'
'\0'

A jak Ty wrzucasz tam jeszcze \0, to robi się z tego:

'a'
'b'
'c'
'\0'
'\0'

Bo po prostu w momencie gdy piszesz w C tekst w cudzysłowach, to znak '\0' jest tam automatycznie doklejany. Skasuj więc to \0 ze swoich stringów i powinno być OK (chyba że błąd masz gdzieś indziej, nie wgłębiałem się, a te \0 rzuciły mi się w oczy).

0

Tu raczej chodzi o offsety. Bo to, czy będzie jedno zero więcej czy nie, nie ma aż takiego znaczenia. I tak na sztywno wysyła dwie tablice po 200 bajtów. Wracając do offsetów, ustaw je względem początku struktury gg_send_msg80.

No i atrybuty chyba powinny być ustawione:

char attributes = { 2, 6, 0, 0, 0, 8, 0, 0, 0};
0
0x666 napisał(a)

Tu raczej chodzi o offsety. Bo to, czy będzie jedno zero więcej czy nie, nie ma aż takiego znaczenia. I tak na sztywno wysyła dwie tablice po 200 bajtów. Wracając do offsetów, ustaw je względem początku struktury gg_send_msg80.

No i atrybuty chyba powinny być ustawione:

char attributes = { 2, 6, 0, 0, 0, 8, 0, 0, 0};

Mógł byś to bardziej rozwinąć, ustawiałem offsety ale to samo.. Nie wiem może źle, liczyłem bity do tablicy z tekstem do wysłania i wpisywałem tą wartość. A z tym sztywnym wysyłaniem? Chodzi Ci o to że jest stały rozmiar tablicy w strukturze ?

0

Według tego, co teraz masz, offsety powinny być ustawione tak:

mmss.offset_plain = 220;
mmss.offset_attributes = 420;

Chodzi Ci o to że jest stały rozmiar tablicy w strukturze ?

Tak.

0
0x666 napisał(a)

Według tego, co teraz masz, offsety powinny być ustawione tak:

mmss.offset_plain = 220;
mmss.offset_attributes = 420;

Dalej jest to samo tylko zamiast XAXA dochodzi ^ więc w tym jest problem..
Co do atrybutów to nie wiem czy dobrze zrobiłem

char attributes[9];	/* atrybuty wiadomości */

mmss.attributes[0] = '2';
	mmss.attributes[1] = '6';
	mmss.attributes[2] = '0';
	mmss.attributes[3] = '0';
	mmss.attributes[4] = '0';
	mmss.attributes[5] = '8';
	mmss.attributes[6] = '0';
	mmss.attributes[7] = '0';
	mmss.attributes[8] = '0';

Ale zobacz jak dam wskaźniki na tablice, i będe dynamicznie ustawiał ich rozmiar

char* html_message;        /* treťŠ w formacie HTML (zako˝czona \0) */
   char* plain_message;        /* treťŠ czystym tekstem (zako˝czona \0) */

To będe chyba wysyłał same wskaźniki a nie to na co one wskazują...

0

A kto mówi o wskaźnikach? Wystarczy taka struktura:

struct gg_send_msg80 
{
	int recipient;                
	int seq;                
	int classs;            
	int offset_plain;    
	int offset_attributes;
};

Najpierw ją wysyłasz, a po niej html_message, plain_message i attributes.

0
0x666 napisał(a)

A kto mówi o wskaźnikach? Wystarczy taka struktura:

struct gg_send_msg80 
{
	int recipient;                
	int seq;                
	int classs;            
	int offset_plain;    
	int offset_attributes;
};

Najpierw ją wysyłasz, a po niej html_message, plain_message i attributes.

No w sumie masz racje, tylko najpierw musiał bym to ustawić żeby w ogóle dobrze wysyłało

0

W opisie protkołu znalazłem coś takiego..

Długość treści wiadomości nie powinna przekraczać 2000 znaków. Oryginalny klient zezwala na wysłanie do 1989 znaków. Treść w formacie HTML jest kodowana UTF-8. Treść zapisana czystym tekstem jest kodowana zestawem znaków CP1250. W obu przypadkach, mimo domyślnych atrybutów tekstu, oryginalny klient dodaje informacje o formatowaniu tekstu. Dla HTML wygląda to następująco:

Treść

Dla czystego tekstu dodawane są informacje o tym, że tekst ma kolor czarny:

0

Coś w ten deseń:

string plain_text; 	//<--- w CP1250
string html_text; 	//<--- w utf8
static const char attributes[] = { 2, 6, 0, 0, 0, 8, 0, 0, 0};

(...)

mmss.offset_plain = sizeof(gg_send_msg80) + html_text.size() + 1;   
mmss.offset_attributes = mmss.offset_plain + plain_text.size() + 1;

(...)

header.type = GG_SEND_MSG80;
header.length = mmss.offset_attributes + sizeof(attributes);

send(sockd,&header, sizeof(header),0); 
send(sockd,&mmss,sizeof(gg_send_msg80),0);
send(sockd,html_text.c_str(),html_text.size() + 1,0);
send(sockd,plain_text.c_str(),plain_text.size() + 1,0);
send(sockd,attributes,sizeof(attributes),0);

Ten kod jest poglądowy, te wszystkie sendy powinny być sprawdzone...

0
	std::string plain_text = "elo";         //<--- w CP1250
	std::string html_text;         //<--- w utf8
	static const char attributes[] = { 2, 6, 0, 0, 0, 8, 0, 0, 0};

	mmss.recipient = 2357907;		/* numer odbiorcy */
	mmss.seq=rand() % 65000;		/* numer sekwencyjny */
//	//mmss.classs=0x0008;		/* klasa wiadomości */
	mmss.classs=0x0020;		/* klasa wiadomości */	

	mmss.offset_plain = sizeof(gg_send_msg80) + html_text.size() + 1;   
	mmss.offset_attributes = mmss.offset_plain + plain_text.size() + 1;

		header.type = GG_SEND_MSG80;
	header.length = sizeof(gg_send_msg80) + mmss.offset_attributes + sizeof(attributes);

	if(send(sockd, (char*)&header, sizeof(header),0))
	{
		printf("Wyslano header\n");
	}
	if(send(sockd,(char*)&mmss,sizeof(gg_send_msg80),0))
	{
		printf("Wyslano strukture\n");
	}
	if(send(sockd,(char*)html_text.c_str(),html_text.size() + 1,0))
	{
		printf("Wyslano html_text\n");
	}
	if(send(sockd,(char*)plain_text.c_str(),plain_text.size() + 1,0))
	{
		printf("Wyslano plain_text\n");
	}
	if(send(sockd,(char*)attributes,sizeof(attributes),0))
	{
		printf("Wyslano attributes\n");
	}

Ok wiadomości nie dochodzą, ale wydaje mi się że to wina kodowania ponieważ nie koduje na CP1250, ale zaraz się tym zajmę

0

Nie dochodzą, bo z tego co pamiętam, wiadomość musisz wysyłać przede wszystkim jako html, plain jest raczej dla starszych wersji klienta (po drugiej stronie).

0
0x666 napisał(a)

Nie dochodzą, bo z tego co pamiętam, wiadomość musisz wysyłać przede wszystkim jako html, plain jest raczej dla starszych wersji klienta (po drugiej stronie).

Jak wpisuje do stringa z html jakis tekst to też nie dochodzą wiadomości, albo kodowania albo musze wstawić coś w stylu Treść tak jak pisało w protokole...

0

A, jest błąd, zrób tak:

header.length = mmss.offset_attributes + sizeof(attributes);
0
0x666 napisał(a)

A, jest błąd, zrób tak:

header.length = mmss.offset_attributes + sizeof(attributes);

Dzię○ki pomogło:)

A słuchaj odbieram wiadomości tak:


		#define GG_RECV_MSG80 0x002e
	//
	struct gg_recv_msg80 {
		int sender;		/* numer nadawcy */
		int seq;		/* numer sekwencyjny */
		int time;		/* czas nadania */
		int classs;		/* klasa wiadomości */
		int offset_plain;	/* położenie treści czystym tekstem */
		int offset_attributes;	/* położenie atrybutów */
		char html_message[2000];	/* treść w formacie HTML (zakończona \0) */
		char plain_message[2000];	/* treść czystym tekstem (zakończona \0) */
		char attributes[9];	/* atrybuty wiadomości */
	}ggreccc;
	
		recv(sockd, (char*)&returned, sizeof(returned) ,0);
	//	printf("\r[+] ret 0x%x!\n", returned.type);
	
	recv(sockd, (char*)&ggreccc, sizeof(ggreccc) ,0);
	std::cout << ggreccc.html_message << std::endl;
	printf(ggreccc.html_message);

Wysyłam z orginalnego klienta tekst np. adrian adrian a wyświetla mi się drian
O ile dobrze rozumiem błąd to powinienem najpierw odebrać sturkture tą co wysyłałem a dopiero potem odebrać tekst i atrybuty bo może być problem z rozmiarem... Rozmiar tablicy atrybutów jest zawsze stały ? 9 ?

0

Rozmiar tablicy atrybutów jest zawsze stały ? 9 ?

Nie, może być różny. Ale to nie jest problem z dwóch względów:

  • gg_header zawiera rozmiar całego pakietu, więc łatwo obliczyć rozmiar tablicy atrybutów.
  • atrybuty raczej nie są Ci do niczego potrzebne. Ważne, żebyś odebrał cały pakiet.

--- edit ---

struct gg_recv_msg80 
{
	int sender;                /* numer nadawcy */
	int seq;                /* numer sekwencyjny */
	int time;                /* czas nadania */
	int classs;                /* klasa wiadomości */
	int offset_plain;        /* położenie treści czystym tekstem */
	int offset_attributes;        /* położenie atrybutów */
};


(...)

vector<char> buf(header.length);

recv(sockd,&buf[0],buf.size(),0);

gg_recv_msg80* gg_msg = (gg_recv_msg80*) &buf[0];
string html_msg_text = &buf[sizeof(gg_recv_msg80)];
string plain_msg_text = &buf[gg_msg->offset_plain];

p.s. recv i send nie muszą odebrać/wysłać dokładnie tyle bajtów, ile podasz im w parametrach. Może być tych bajtów mniej, powinieneś mieć to na względzie.

0
0x666 napisał(a)

Rozmiar tablicy atrybutów jest zawsze stały ? 9 ?

Nie, może być różny. Ale to nie jest problem z dwóch względów:

  • gg_header zawiera rozmiar całego pakietu, więc łatwo obliczyć rozmiar tablicy atrybutów.
  • atrybuty raczej nie są Ci do niczego potrzebne. Ważne, żebyś odebrał cały pakiet.

--- edit ---

struct gg_recv_msg80 
{
	int sender;                /* numer nadawcy */
	int seq;                /* numer sekwencyjny */
	int time;                /* czas nadania */
	int classs;                /* klasa wiadomości */
	int offset_plain;        /* położenie treści czystym tekstem */
	int offset_attributes;        /* położenie atrybutów */
};


(...)

vector<char> buf(header.length);

recv(sockd,&buf[0],buf.size(),0);

gg_recv_msg80* gg_msg = (gg_recv_msg80*) &buf[0];
string html_msg_text = &buf[sizeof(gg_recv_msg80)];
string plain_msg_text = &buf[gg_msg.offset_plain];

p.s. recv i send nie muszą odebrać/wysłać dokładnie tyle bajtów, ile podasz im w parametrach. Może być tych bajtów mniej, powinieneś mieć to na względzie.

Tak ale jak bym chciał obliczyć to mam przecież tylko długość pakietu i 2 nie wiadome ( długość przesyłanego tekstu i ilość atrybutów )

Co do kodu to nie wiem, wywala mi program jak już działa z informacją o przekroczeniem vectora, przerobiłem bo nie używając vectora tylko na czystych tablicach:

			char* bb;
	bb = new char[header.length];
	recv(sockd,bb,header.length,0);

gg_recv_msg80* gg_msg = (gg_recv_msg80*) bb;
for(int i = sizeof(gg_recv_msg80); i < gg_msg->offset_plain; i++)
{
	html_msg_text += bb[i];
}

Ale w tym wypadku żadne znaki nie są kopiowane do stringa.

0

Co do kodu to nie wiem, wywala mi program jak już działa z informacją o przekroczeniem vectora

W którym miejscu, bo nie widzę nigdzie błędu?

0
0x666 napisał(a)

Co do kodu to nie wiem, wywala mi program jak już działa z informacją o przekroczeniem vectora

W którym miejscu, bo nie widzę nigdzie błędu?

www.coubetech.republika.pl/bladd.jpg
Tylko że debuger nie pokazuje miejsca w kodzie tylko zamyka cały program.

druga sprawa to VC pokazuje błąd tutaj:
std::string plain_msg_text = &buf[gg_msg.offset_plain]; . na -> bo to wskaźnik, ale mniejsza o to bo ten string nie jest mi potrzebny...

0

No nie wiem, nie widzę błędu. Jedyna opcja może taka, że vector jest jakimś cudem pusty.

Czy nie robisz przypadkiem:

(...)

vector<char> buf(header.length);

/* tu czytasz 'header' z socketa */

(...)

???

druga sprawa to VC pokazuje błąd tutaj: (...)

No tak, drobny bład. Piszę z palca, więc błędy mogą się pojawić... zresztą pisałem, że to kod poglądowy.

0
0x666 napisał(a)

No nie wiem, nie widzę błędu. Jedyna opcja może taka, że vector jest jakimś cudem pusty.

Czy nie robisz przypadkiem:

(...)

vector<char> buf(header.length);

/* tu czytasz 'header' z socketa */

(...)

???

Czytam przed

0x666 napisał(a)

druga sprawa to VC pokazuje błąd tutaj: (...)

No tak, drobny bład. Piszę z palca, więc błędy mogą się pojawić... zresztą pisałem, że to kod poglądowy.

Oj toż wiadomo

0

Czytam przed

Pokaż większy kawałek kodu.

0
0x666 napisał(a)

Czytam przed

Pokaż większy kawałek kodu.

#define GG_RECV_MSG80 0x002e
	
struct gg_recv_msg80
{
        int sender;                /* numer nadawcy */
        int seq;                /* numer sekwencyjny */
        int time;                /* czas nadania */
        int classs;                /* klasa wiadomości */
        int offset_plain;        /* położenie treści czystym tekstem */
        int offset_attributes;        /* położenie atrybutów */
};

	recv(sockd, (char*)&header, sizeof(header) ,0);
	if(header.type == GG_RECV_MSG80)
	{
		std::cout << "wiad" << std::endl;
	}

	vector<char> buf(header.length);

recv(sockd,&buf[0],buf.size(),0);

gg_recv_msg80* gg_msg = (gg_recv_msg80*) &buf[0];
std::string html_msg_text = &buf[sizeof(gg_recv_msg80)];
std::string plain_msg_text = &buf[gg_msg->offset_plain];

Debuger zatrzymał się na ostatniej linijce. Ale staram się to jakoś napisać w czystym C...

0

Sprawdź jaki jest rozmiar całego pakietu i ile ma offset_plain.

0
0x666 napisał(a)

Sprawdź jaki jest rozmiar całego pakietu i ile ma offset_plain.

Przy wiadomości elo rozmiar pakietu to 29 a offset_plain 7302245 czyli znacznie przekracza rozmiar pakietu...

0

No właśnie. Podejrzewam, że problemem jest to, o czym pisałem w tym poście w post scriptum - recv nie czyta całego pakietu. Sprawdź co zwraca.

Z drugiej strony to trochę dziwne, bo pakiet jest mały...

0
0x666 napisał(a)

No właśnie. Podejrzewam, że problemem jest to, o czym pisałem w tym poście w post scriptum - recv nie czyta całego pakietu. Sprawdź co zwraca.

Z drugiej strony to trochę dziwne, bo pakiet jest mały...

Jest na to recepta ? Ale przecież to połączenie TCP to powinny dochodzić...

EDIT: recv zwraca 29 czyli tyle ile wynosi rozmiar pakietu..

0

OK, czyli coś nie tak z wiadomością. Z czego ją wysyłasz? Oryginalny klient, czy alternatywny?

Ale przecież to połączenie TCP to powinny dochodzić...

Owszem, ale recv nie musi na raz przeczytać żądanej ilości bajtów, może przeczytać mniej, bo akurat tyle w danej chwili jest w buforze. To samo z send.

0
0x666 napisał(a)

OK, czyli coś nie tak z wiadomością. Z czego ją wysyłasz? Oryginalny klient, czy alternatywny?

Ale przecież to połączenie TCP to powinny dochodzić...

Owszem, ale recv nie musi na raz przeczytać żądanej ilości bajtów, może przeczytać mniej, bo akurat tyle w danej chwili jest w buforze. To samo z send.

Orginalny klient. Ale ten problem można chyba rozwiązać pętlą przy send czy recv tak ?

0

Cytujesz cały post i nie wiem odnośnie czego jest to Twoje pytanie. Cytuj fragmentami, żeby było wiadomo o co pytasz.

Klient w wersji 6?

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