CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - TCPClient Indy i unsigned char

TCPClient Indy i unsigned char

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

TCPClient Indy i unsigned char

Nowy postprzez deus100 » wtorek, 18 lutego 2014, 09:47

Witam serdecznie wszystkich na forum.
Staram się wysłać tablicę znaków poprzez TCP Indy w postaci:

KOD cpp:     UKRYJ  
char dane[7];

dane[0]=0x21;
dane[1]=0x89;
dane[2]=0x01;
dane[3]=0x49;
dane[4]=0x50;
dane[5]=0x36;
dane[6]=0x0A;

IdTCPClient1->Socket->Write(dane);

Wszystko było by OK, lecz zamiast 0x89 wysyła mi "3F" (? w ASCII). Ogólnie wszystko powyżej dec 128 wysyła jako 3F. Rozwiązaniem byłoby zadeklarowanie unsigned char zamiast char, ale TCPClient nie chce wysyłać unsigned. Jak mogę w prosty sposób rozwiązać ten problem?
Dzięki wielkie za wszelką pomoc.
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Re: TCPClient Indy i unsigned char

Nowy postprzez polymorphism » wtorek, 18 lutego 2014, 10:22

Zgaduje, że Write służy do wysyłania tekstu a nie danych binarnych, być może następuje jakaś konwersja przed wysłaniem i stąd te przekłamania. Użyj jakiejś metody do wysyłania/odbierania danych binarnych (nie powiem Ci jaka, bo nie mam dokumentacji INDY).


KOD cpp:     UKRYJ  
char dane[7] = { 0x21, 0x89, 0x01, 0x49, 0x50, 0x36, 0x0A };

Tak chyba prościej i czytelniej, prawda?
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
    Windows XPFirefox

Re: TCPClient Indy i unsigned char

Nowy postprzez deus100 » wtorek, 18 lutego 2014, 10:29

Można też przez Write wysłać unsigned char, ale jako pojedynczy znak (i wychodzi na sieć dobrze, czyli 0x89), a nie tablicę. Jeśli przekonwertuje to do string (0x89 to znak promila) i wyślę poprzez Write także wysyła 0x3F.
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Re: TCPClient Indy i unsigned char

Nowy postprzez polymorphism » wtorek, 18 lutego 2014, 10:56

Wysyłając pojedynczy znak, używasz innego wariantu metody Write do wysyłania pojedynczego bajta/8-bitowej wartości liczbowej, dlatego to działa. Jeszcze raz napiszę: jak chcesz wysłać dane binarne, użyj odpowiednich do tego celu metod (według dokumentacji jest wersja Write, która przyjmuje parametr typu TIdBytes (alias System.SysUtils.TBytes), może z tym typem zadziała).
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
    Windows XPFirefox

Re: TCPClient Indy i unsigned char

Nowy postprzez Cyfrowy Baron » wtorek, 18 lutego 2014, 11:29

deus100 napisał(a):Jeśli przekonwertuje to do string (0x89 to znak promila)


Znak promila (°) to znak Unicode. Konwertujesz na String - jeżeli używasz starszej wersji środowiska niż C++Builder 2010, to String = AnsiString, więc AnsiString nie przechowa znaku unicode. char też w zasadzie nie powinien obsługiwać unicode. W nowszych wersjach środowiska jest wchar_t dla UnicodeString.

Poza tym write obsługuje więcej typów:

write.png
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
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
    Windows 7Firefox

Re: TCPClient Indy i unsigned char

Nowy postprzez deus100 » środa, 19 lutego 2014, 09:25

BCB 6, INDY 10. Gdy korzystam z UDPClient to spokojnie char pomieści wszystkie wartości do 255 i bez marudzenia wysyła całą tablicę. Program Hercules przez TCP i zaznaczonych hexach też wysyła poprawnie. Jak to mogę jeszcze przepchnąć przez inne parametry Write?
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Re: TCPClient Indy i unsigned char

Nowy postprzez Cyfrowy Baron » środa, 19 lutego 2014, 12:21

Nie wiem. BCB 6 to przestarzałe środowisko. Pisałeś, że konwertujesz char na String - po co? Sprawdź czy przejdzie char bez konwersji.
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
    Windows 7Firefox

Re: TCPClient Indy i unsigned char

Nowy postprzez deus100 » środa, 19 lutego 2014, 13:17

W BCB 6 mam bardzo rozległy program napisany i nie mogę zmienić, a to ma być dodatek do niego. Konwertowałem do Stringa tylko jako sprawdzenie. Char jako jeden znak oraz tablice wysyła wszystko powyżej 0x80 jako 0x3F. Unsigneg char jeden znak wysyła dobrze, ale Write już nie potrafi wysłać tablicy unsigned. :( a muszę wysłać te znaki jeden po drugim zaraz po innych komendach sterujących.
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Re: TCPClient Indy i unsigned char

Nowy postprzez Mironas » środa, 19 lutego 2014, 15:16

A musi być TCP? Ja kiedyś testowałem coś podobnego w UDP i działało poprawnie.

Wysyłanie:
KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char ch[3] = {56, 129, 200};
  String dane = ch;
  IdUDPClient1->Active = true;
  IdUDPClient1->Send(dane);
  IdUDPClient1->Active = false;
}
 


Odbieranie:
KOD cpp:     UKRYJ  
void __fastcall TForm1::IdUDPServer1UDPRead(TObject *Sender, TStream *AData, TIdSocketHandle *ABinding)
{
  AnsiString s;
  char buff[3];

  AData->Read(buff, 3);
  s = buff;
  s.SetLength(3);
  //ListBox1->Items->Add(s);

  // kody znakow
  byte kod;
  String wiersz = s + "  ";
  for (int i=0 ; i<s.Length() ; i++)
  {
    kod = buff[i];
    wiersz = wiersz + "{"+IntToStr(kod)+"} ";
  }
  ListBox1->Items->Add(wiersz);
}
//---------------------------------------------------------------------------
 
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: TCPClient Indy i unsigned char

Nowy postprzez deus100 » środa, 19 lutego 2014, 15:57

Niestety musi być TCP (handshake itp). Z UDP mam inną transmisję i działa jak już pisałem dobrze. Znalazłem coś takiego:
IdTCPClient1->Socket->Write(dane, TIdTextEncoding_UTF8); // dodaje kilka znaków zamiast 0x89
IdTCPClient1->Socket->Write(dane, TIdTextEncoding_UTF8, TIdTextEncoding_Default); // jak wyżej
IdTCPClient1->Socket->Write(dane, TIdTextEncoding_Default, TIdTextEncoding_UTF8); // nie zmienia nic
Znacie jakieś inne kodowania?
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Re: TCPClient Indy i unsigned char

Nowy postprzez Mironas » środa, 19 lutego 2014, 16:21

Podeślij przykład jak wysyłasz i jak odbierasz.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: TCPClient Indy i unsigned char

Nowy postprzez polymorphism » środa, 19 lutego 2014, 20:11

Mironas napisał(a):
KOD cpp:     UKRYJ  
  char ch[3] = {56, 129, 200};
String dane = ch;

To jest źle. ch nie jest poprawnym c-stringiem - brak zera na końcu. Działa przez przypadek. Tak ma być:
KOD cpp:     UKRYJ  
 char ch[4] = { 56, 129, 200, 0 };
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
    Windows 7Firefox

Re: TCPClient Indy i unsigned char

Nowy postprzez Cyfrowy Baron » środa, 19 lutego 2014, 23:56

polymorphism napisał(a):
KOD cpp:     UKRYJ  
char ch[4] = { 56, 129, 200, 0 };


Nie twierdzę, że to źle, ale wydaje mi się, że wystarczy tak:

KOD cpp:     UKRYJ  
char ch[4] = { 56, 129, 200};


Znak końca zostanie dodany automatycznie.




Co do problemu, podaj kompletny kod, bym mógł go przetestować na swoim środowisku.
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
    Windows 7Firefox

Re: TCPClient Indy i unsigned char

Nowy postprzez polymorphism » czwartek, 20 lutego 2014, 10:33

(...) ale wydaje mi się, że wystarczy tak: (...)

Może być i tak, choć wydaje mi się, że jawne wstawienie zera jest czytelniejsze, bo pokazuje, "co autor miał na myśli".



Może niech deus100 wyjaśni, co chce wysłać. Dane binarne czy jakiś łańcuch znakowy? Z pierwszego postu wynikało, że opcja pierwsza wchodzi w grę, ale teraz widzę, że chodzi o tekst. Więc w końcu jak jest?
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
    Windows XPFirefox

Re: TCPClient Indy i unsigned char

Nowy postprzez deus100 » czwartek, 20 lutego 2014, 14:31

Nie wiem co tego stringa się uczepiliście :) Chodziło o dane wysyłane w czystej postaci hex. Dziękuję za zainteresowanie kolegów, ale sprawa rozwiązana. Chodziło o sposób kodowania znaków przez INDY.
Dla potomnych:

KOD cpp:     UKRYJ  
char dane[7];
// <- tutaj zapisujemy tablice w jaki sposób nam się podoba
IdTCPClient1->Socket->Write(dane, TIdTextEncoding_Default);


Jeszcze raz dzięki za zainteresowanie i pomoc.
Avatar użytkownika
deus100
Bladawiec
Bladawiec
 
Posty: 7
Dołączył(a): wtorek, 18 lutego 2014, 09:29
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows
Kompilator: C++
Gadu Gadu: 0
    Windows 7Chrome

Następna strona

  • 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 3 gości