• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed WinSock, własny protokół binarny

Object Storage Arubacloud
0 głosów
820 wizyt
pytanie zadane 28 listopada 2017 w C i C++ przez icegolem Nowicjusz (160 p.)
zamknięte 29 listopada 2017 przez icegolem

Witam, w ramach zajęć na studiach muszę zaprogramować własny protokół binarny przy użyciu WinSocku. Przesyłam pakiet składający się z pól zawierających pole operacji(2 bity), liczby(3x64bity), status(4bity) i id(4bity).
Przy użyciu std::bitset zamieniam te dane na ciąg bitów, dziele je na kolejne bajty i zamieniam na string. Następnie wysyłam przy użyciu funkcji .c_str(). Problem pojawia się gdy któryś bajt ma wartość 0x00(NULL). W takim przypadku string zostaję ucięty i kolejne chary nie są dodawane to tablicy charów.

komentarz zamknięcia: Nie uzyskałem satysfakcjonującej odpowiedzi, problem rozwiązałem w inny sposób.
komentarz 28 listopada 2017 przez draghan VIP (106,230 p.)
Musisz dokładniej napisać, co robisz. Nie wiadomo, kiedy, gdzie, co dokładnie i dlaczego umieszczasz w tablicy znakowej.
komentarz 28 listopada 2017 przez Bondrusiek Maniak (61,370 p.)

Następnie wysyłam przy użyciu funkcji .c_str(). 

Z tego co pamiętam to w języku C znak '\0' oznaczał koniec napisu. Nawet jak deklarowałeś tablicę to musiałeś uwzględnić ten znak. Być może to jest przyczyną, że masz ucięty napis. Może spróbuj stworzyć algorytm, który po napotkaniu znaku '\0' dzieli napis na części, liczy długość a na wyjściu łączy to wszystko.

komentarz 28 listopada 2017 przez adrian17 Ekspert (344,860 p.)

Może spróbuj stworzyć algorytm, który po napotkaniu znaku '\0' dzieli napis na części, liczy długość a na wyjściu łączy to wszystko.

Nie ma potrzeby, już wszystko jest "połączone" - w std::string-u.

(przynajmniej zakładając, że dobrze rozumiem "zamieniam na string".)

Pewnie gdzieś używasz pośrednio lub bezpośrednio strlen(), podczas, gdy std::string da Ci pełną długość ciągu.

komentarz 28 listopada 2017 przez draghan VIP (106,230 p.)
Problemem na pewno jest interpretacja zera jako znaku '\0', ale bez dokładnych informacji, co jest dokładnie robione, to można sobie pogdybać nad rozwiązaniem. :)

2 odpowiedzi

0 głosów
odpowiedź 28 listopada 2017 przez j23 Mędrzec (194,920 p.)
Jeśli jest to "protokół binarny", to dlaczego wysyłasz go jako łańcuch znakowy?
komentarz 28 listopada 2017 przez adrian17 Ekspert (344,860 p.)

https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms740149(v=vs.85).aspx

int send(
  _In_       SOCKET s,
  _In_ const char   *buf,
  _In_       int    len,
  _In_       int    flags
);

"bufor" jest na pewnym poziomie "łańcuchem znakowym" (nie zakończonym zerem).

komentarz 28 listopada 2017 przez j23 Mędrzec (194,920 p.)
Nie, to po prostu jakiś ciąg bajtów.
komentarz 28 listopada 2017 przez adrian17 Ekspert (344,860 p.)
...tak; ten ciąg bajtów na poziomie języka C++ jest zazwyczaj używany za pośrednictwem zmiennej typu char* lub std::string.
komentarz 28 listopada 2017 przez j23 Mędrzec (194,920 p.)

Na poziomie C++ do takich rzeczy jest std::vector, a nie std::string.

komentarz 28 listopada 2017 przez adrian17 Ekspert (344,860 p.)
Oba są akceptowalne, ale OK :)
0 głosów
odpowiedź 28 listopada 2017 przez icegolem Nowicjusz (160 p.)
//POLA KLASY PACKET
	int type; //typ działania arytmetyczno-logicznego, 2 bity
	long long num1; //pierwsza liczba, 64 bity
	long long num2; //druga liczba, 64 bity
	long long num3; //trzecia liczba, 64 bity
	int state; //pole statusu, 4 bity
	int id; //identyfikator sesji, 4 bity
//SERIALIZACJA PAKIETU
	std::string Packet::packetToString() 
	{
		//serializacja poszczególnych pól i łączenie w jeden bitset
		std::bitset<208> pak(std::string(std::bitset<2>(type).to_string() + std::bitset<64>(num1).to_string() + std::bitset<64>(num2).to_string() + std::bitset<64>(num3).to_string() + std::bitset<4>(state).to_string() + std::bitset<4>(id).to_string() + "000000")); //208 bitowy bitset złożony z połączonych pól
		std::string temp;
		std::bitset<8> tempBitset(0);
		//podział dużego bitsetu na bajty
		for (int i = pak.size() - 1; i >= 0; i--)
		{

			tempBitset[i % 8] = pak[i];
			if (i % 8 == 0)
			{
				//zamiana bajtów na chary
				char t = static_cast<char> (tempBitset.to_ulong());
				//łączenie w pojedynczy string
				temp.push_back(t);
			}

		}
		return temp;
	}
//WYSYŁANIE PAKIETU
void UDPSocket::SendTo(const std::string &address, unsigned short port, string &packet, int len, int flags)
{
	sockaddr_in add;
	add.sin_family = AF_INET;
	add.sin_addr.s_addr = inet_addr(address.c_str());
	add.sin_port = htons(port);
	int ret = sendto(sock, packet.c_str(), len, flags, (sockaddr*)&add, sizeof(add));
	if (ret < 0)
		throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
}

Jeśli podam odpowiednio duże liczby, dla których żaden char nie przyjmuje wartości 0x00, cały pakiet się wysyła i wszystko działa bez problemu, w innym wypadku wysyła tylko do wystąpienia pierwszego nulla.

Podobne pytania

0 głosów
2 odpowiedzi 333 wizyt
pytanie zadane 19 maja 2018 w C i C++ przez Mamrotek Nowicjusz (180 p.)
0 głosów
0 odpowiedzi 361 wizyt
0 głosów
1 odpowiedź 154 wizyt
pytanie zadane 12 lutego 2018 w C i C++ przez Hiskiel Pasjonat (22,830 p.)

92,568 zapytań

141,420 odpowiedzi

319,618 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...