SqRobert Posted May 11, 2014 Report Share Posted May 11, 2014 As vrea si eu un ghid clar sau niste exemple cum as putea sa stochez date in cate un byte sau daca pot concatena la un char* pentru ca la finaltrebuie sa-l transmit prin parametru char*.int sendto( _In_ SOCKET s, _In_ const char *buf, _In_ int len, _In_ int flags, _In_ const struct sockaddr *to, _In_ int tolen);Intentia mea e sa creez un sir lung de bytes cu date de tip , string , int , long , enum orice tip sa il pot stoca in cate un byte sau mai multi daca depaseste capacitatea si adaugat la un sir intreg Quote Link to comment Share on other sites More sharing options...
nedo Posted May 11, 2014 Report Share Posted May 11, 2014 Nu e asa simplu sa faci asta. Problema principala e urmatoarea, cum iti dai seama unde incepe si unde se termina o variabila si incepe alta in sir-ul tau?Daca ai date de transmis prin retea, atunci cel mai ok ar fii sa trimiti datele pe rand.Daca e vorba de vreun struct/class atunci trimiti membri, iar la celalalt capat ii citesti si construiesti un nou obiect(struct sau class).Trebuie insa sa tii cont de cum ajung datele, trebuie sa gasesti si acolo o metoda sa delimitezi ce trimiti, cand trimiti.Eu in general incerc sa fac ceva gen pachete, verific daca ce am de transmis e mai mare de 255 bytes. Daca nu este, trimit 0 pentru ca este mai mic decat 255 si dupa trimit numarul de bytes pe care trebuie sa ii citesc, dupa care trimit ce am de trimis.Daca am mai mult de 255 bytes, trimit numarul de block-uri de 255 bytes(spre exemplu am 1024 bytes de transmis), in cazul asta 4, urmat de numarul de bytes ramasi de transmis(4).Ambele numere le transmit sub forma de unsigned char(poate sa contina valori de la 0 la 255) iar cand le primesc le transform in int.Nu stiu daca e cea mai eficienta solutie sau cea mai buna, dar la ultimele programe la care am lucrat cu sockets, asa am facut si mi-a mers bine. 1 Quote Link to comment Share on other sites More sharing options...
SqRobert Posted May 11, 2014 Author Report Share Posted May 11, 2014 Nu vreau si nu pot sa folosesc inca structuri sau clase, merg treptat. Mesajul il recunosc dupa NetworkMessageType.enum NetworkMessageType{ NetworkMessageType_Invalid = 1, NetworkMessageType_Join = 2, NetworkMessageType_UpdateFromClient_Input = 4, NetworkMessageType_UpdateFromServer_Input = 8,};Actual pentru setarea mesajului folosesc asta*reinterpret_cast<NetworkMessageType*>(m_Buffer) = NetworkMessageType_Join;Pe viitor o sa adaug in primul byte 8 mesaje folosing bit flags sau primi doi bytes in functie de cat voi avea nevoie. urmat de numarul de bytes ocupat de informatia de urmeaza.buff[0] = NetworkMessageTypesbuff[1] = 2 next bytes used (Message Type Position)buff[2] = position.xbuff[3] = position.ybuff[4] = 8 bytes used (Message Type Position(X,Y) 4 enemies)1. Cum adaug 1024 intr-un byte?2. E bine sa folosesc un array de char-uri? Daca da cum transform 1 short int intr-un singur byte daca stiu clar ca nu depasesc acea memorie? Ma folosesc de bitwise operators?Am gasit un exemplu Exemplu: char myChar[20];unsighed short s_int = 800; myChar[0] = s_int -->convert 1 byte of short int into char; Ce am gasit. Asta imparte cei 2 bytes in cate un char.buff[0] = s_int & 0xff;buff[1] = (s_int >> 8) & 0xff;3:Ce reprezinta? 0xff? Nu am gasit prea multe pe google. Multumesc ,apreciez ajutorul oferit! Quote Link to comment Share on other sites More sharing options...
nedo Posted May 11, 2014 Report Share Posted May 11, 2014 Cat despre transformat din tipuri fundamentale(int, double, float) in char, folosesti reinterpret_cast si marimea tipului.Spre exemplu:#include <iostream>#include <cstring>using namespace std;int main() { unsigned char* bts = new unsigned char[sizeof(double)]; // char array de marimea unui double double d = 123.45; // double-ul nostru memcpy(bts, &d, sizeof(double)); // copiem la adresa lui bts continutul adresei &d continand sizeof(double) bytes cout << bts << endl; // printam continutul array-ului bts double dd; memcpy(&dd, bts, sizeof(double)); // copiem la adresa lui dd continutul array-ului bts cu marimea sizeof(double) bytes cout << dd; return 0;}0xff inseamna 255, intai mascheaza primi 8 biti din stanga(ii seteaza la 0) si copiaza ceea ce ramane adica ceilalti 8 biti care reprezinta prima parte a short-ului.Dupa care muta primi 8 biti din stanga, 8 biti mai la dreapta, si mascheaza biti ramasi in loc.Codul de mai jos ar trebui sa iti explice destul de clar exact ce se intampla. char asdf[3]; unsigned short s_int = 800; bitset<16> x_s_int(s_int); asdf[0] = s_int & 0xff; // preia primul byte prin mascarea celorlalti biti asdf[1] = (s_int >> 8) & 0xff; asdf[2] = '\0'; bitset<16> x_ff(0xff); cout << asdf << endl; unsigned short s; memcpy(&s, asdf, sizeof(unsigned short)); cout << s << endl; cout << "s_int =\t " << x_s_int << endl; cout << "0xff =\t " << x_ff << endl; bitset<16> x_asdf_0(asdf[0]); bitset<16> x_asdf_1(asdf[1]); cout << "s_int & 0xff; = " << x_asdf_0 << endl; cout << "(s_int >> 8) & 0xff;" << x_asdf_1 << endl;cifer este un std::string.Pentru a vedea cate bucati am impart marimea la ce am de trimis(in cazul asta in cate caractere sunt/sau cati bytes sunt)la marimea maxima a unei bucati(255);si fac calculele necesare.Mai jos un exemplu const int BUFF_SIZE = 255; // max size of the chunks unsigned char chunks = cifer.size() / BUFF_SIZE; // number of chuncks that compose our encrypted message if((chunks * BUFF_SIZE) > cifer.size()) // checking if it rounded up { chunks--; } unsigned char lastChunkSize = cifer.size() - (chunks * BUFF_SIZE); // size of the last chunk mp_sockClient->Write(&chunks, 1); // sending the number of chunks mp_sockClient->Write(&lastChunkSize, 1); // sending the size of the last chunk mp_sockClient->Write(cifer.c_str(), cifer.size()); // sending the whole encrypted messagePentru citire fac ceva de genul asta unsigned char chunks; // number of 255 bytes chunks will be received unsigned char lastChunkSize; // size of the last chunk mp_sockClient->Read(&chunks, 1); // reading number of chuncs from socket mp_sockClient->Read(&lastChunkSize, 1); // reading size of last chunk from socket // loop to read every 255 bytes chunk and append it to cifer for(int i = 0; i < chunks; i++) { char buff[255]; mp_sockClient->Read(buff, 255); cifer.append(buff, 255); } char* lastBuff = new char[lastChunkSize];// new buffer with the size of the last chunk mp_sockClient->Read(lastBuff, lastChunkSize);// readin it cifer.append(lastBuff, lastChunkSize); // apending itPana acum nu m-am complicat insa cu biti, totusi operatiile nu ar trebui sa fie diferite atat timp cat lucrezi cu int-uri mai mici de 255 si folosesti unsigned char; Quote Link to comment Share on other sites More sharing options...
SqRobert Posted May 12, 2014 Author Report Share Posted May 12, 2014 A fost de mare ajutor , mersi! Quote Link to comment Share on other sites More sharing options...
compile Posted May 12, 2014 Report Share Posted May 12, 2014 Nu trebuie sa-i dai neaparat char chiar daca functia asta cere. Poti sa-i dai orice adresa de memorie si el va trimite ce gaseste acolo byte cu byte pana acopera dimensiunea data.De ex ca sa trimiti:int ival = 42;send(0, (char*)&ival, sizeof(int), 0); //sizeof(int) = 4si ca sa primesti:int ival = 42;recv(0, (char*)&ival, sizeof(int), 0); Quote Link to comment Share on other sites More sharing options...