Socket->ReceiveBuf - rozpoznawanie struktur

problemy z tworzeniem programów do obsługi sieci, internetu, e-mail itp..

Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Koziol » środa, 21 października 2009, 23:16

Jak rozpoznawać przesłane struktury?
Przykładowo przez sockety mam możliwośc przesyłania 3 struktur.
Kod: Zaznacz cały
struct _a {
String a;
String b;
} a;

struct _b {
int d;
String w;
} b;

struct _c {
int s;
int w;
} c;

W jaki sposób rozpoznać która jest która przy odbieraniu danych?
Rozpoznawanie po rozmiarze nie sprawdzi się - mogą zdażyć sie dwie struktury o tym samym rozmiarze.
Avatar użytkownika
Koziol
Intelektryk
Intelektryk
 
Posty: 144
Dołączył(a): niedziela, 13 lipca 2008, 17:36
Podziękował : 8
Otrzymał podziękowań: 2
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Cyfrowy Baron » czwartek, 22 października 2009, 08:24

Kod: Zaznacz cały
struct _a {
String a;
String b;
} a;
struct _b {
int d;
String w;
} b;



Te struktury ze zmienną String mogą nie działać prawidłowo, lepiej zastąp je typem char.
Co do rozpoznawania struktur to musisz dodać po jednej zmiennej identyfikacyjnej do każdej, może to być typ int:

Kod: Zaznacz cały
    struct _a {
    String a;
    String b;
   
    int idx = 0;
    } a;

    struct _b {
    int d;
    String w;
   
    int idx = 1;
    } b;

    struct _c {
    int s;
    int w;

    int idx = 2;
    } c;


Po odebraniu danych przesłanych przez strukturę program sprawdzi wartość tej zmiennej i będzie wiedział z którą strukturą ma do czynienia.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Koziol » czwartek, 22 października 2009, 08:58

Też się zastanawiałem nad tymi string'ami, ok zmienie.

A w jaki sposób dobrać się do tej zmiennej idx? Przecież nie wiedząc z którą strukturą mamy do czynienia trzeba ją zapisać do void (o odpowiedniej wielkości).
Avatar użytkownika
Koziol
Intelektryk
Intelektryk
 
Posty: 144
Dołączył(a): niedziela, 13 lipca 2008, 17:36
Podziękował : 8
Otrzymał podziękowań: 2
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Cyfrowy Baron » czwartek, 22 października 2009, 10:15

Ja nie wiem jak masz skonstruowaną funkcję pobierającą strukturę, ale pomyśl - program wysyła całą strukturę, każda struktura zawiera zmienną idx, program musi najpierw odebrać strukturę, potem sprawdzić wartość zmiennej idx i już wie z jaką strukturą ma do czynienia.

A w jaki sposób dobrać się do tej zmiennej idx? Przecież nie wiedząc z którą strukturą mamy do czynienia trzeba ją zapisać do void (o odpowiedniej wielkości).


Nie rozumiem. Struktura ma określoną wielkość, dlatego nie możesz użyć zmiennej typu String.

Przykład z czytaniem struktury z pliku:

Kod: Zaznacz cały
struct _a {
String a;
String b;
} a;

_a Baza_a;

fstream infile;                                 
infile.open("Test.dat", ios::in | ios::binary);
infile.read((char *)&Baza_a, sizeof(Baza_a));


Na prawdę nie rozumiem o co Tobie chodzi z tym void.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez polymorphism » czwartek, 22 października 2009, 11:37

W jaki sposób rozpoznać która jest która przy odbieraniu danych?

Musisz nadać każdej odpowiednie ID, zrozumiałe dla obu stron - to oczywiste. Pakiet może się składać z jednobajtowego ID i struktury:
Kod: Zaznacz cały
enum
{
   packet_A = 0;
   packet_B;
   packet_C;
};

struct a { ... };
struct b { ... };
struct c { ... };

Przy odbieraniu pakietu czytasz ID i na podstawie jego wartości określasz typ struktury:
Kod: Zaznacz cały
unsigned char id;

socket.read(&id,1);
switch(id)
{
case packet_A:
   {
      a data;
      socket.read(&data,sizeof(data));
      ...
   }
   
case packet_B:
   {
      b data;
      socket.read(&data,sizeof(data));
      ...
   }

case packet_C:
   {
      c data;
      socket.read(&data,sizeof(data));
      ...
   }

   ...
};

Analogicznie wysyłasz.



WAŻNE: Struktury, które wysyłasz w sieć powinny być wyrównane do jednego bajta.



Przecież nie wiedząc z którą strukturą mamy do czynienia trzeba ją zapisać do void (o odpowiedniej wielkości).

Nie do void, tylko do jakiegoś bufora o odpowiedniej wielkości.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Koziol » wtorek, 17 listopada 2009, 13:51

Znalazłem rozwiązanie mam nadzieję że słuszne.
Stwierdziłem że opłaca się w tym wypadku zastosować funkcje CopyMemory (http://msdn.microsoft.com/en-us/library/aa366535%28VS.85%29.aspx) w następujący sposób:
Kod: Zaznacz cały

#include <windows.h>
(...)
void * Buffer;
int idx;
int size;
size = Socket->ReceiveLength();
void * Buffer = malloc(size);
CopyMemory(&idx, &Buffer, sizeof(int));
switch(idx)
{
(...)
}



Co o takim rozwiązaniu myślicie?

Pozdrawiam.
Avatar użytkownika
Koziol
Intelektryk
Intelektryk
 
Posty: 144
Dołączył(a): niedziela, 13 lipca 2008, 17:36
Podziękował : 8
Otrzymał podziękowań: 2
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez polymorphism » wtorek, 17 listopada 2009, 15:32

Stwierdziłem że opłaca się w tym wypadku zastosować funkcje CopyMemory

Akurat w tym przypadku nie opłaca się. Sensowniej będzie tak:
Kod: Zaznacz cały
idx = *((int*)Buffer);
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Koziol
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Koziol » wtorek, 17 listopada 2009, 15:39

polymorphism napisał(a):
Stwierdziłem że opłaca się w tym wypadku zastosować funkcje CopyMemory

Akurat w tym przypadku nie opłaca się. Sensowniej będzie tak:
Kod: Zaznacz cały
idx = *((int*)Buffer);

Hm. Faktycznie działa z góry dziękuje :)
PS. Użycie CopyMemory spowolniło by po prostu prace programu jak mniemam?
Avatar użytkownika
Koziol
Intelektryk
Intelektryk
 
Posty: 144
Dołączył(a): niedziela, 13 lipca 2008, 17:36
Podziękował : 8
Otrzymał podziękowań: 2
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez polymorphism » wtorek, 17 listopada 2009, 15:44

W tym przypadku nie, ale jeśli pewne rzeczy możesz zrobić w prosty i, co najważniejsze, logiczny sposób, to zrób to -> zasada KISS.

___
p.s. i jak rozwiązałeś problem identyfikacji pakietów?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Socket->ReceiveBuf - rozpoznawanie struktur

Nowy postprzez Koziol » wtorek, 17 listopada 2009, 15:52

Tak udało mi się rozwiązać - kończę właśnie klasę SocketController (połączenie Client/ServerSocket z obsługą pakietów) zamieszczę ją potem do oceny :)
Avatar użytkownika
Koziol
Intelektryk
Intelektryk
 
Posty: 144
Dołączył(a): niedziela, 13 lipca 2008, 17:36
Podziękował : 8
Otrzymał podziękowań: 2
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder
    NieznanyNieznana


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje sieciowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron