Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Pakettien jakaminen megoiksi

Sivun loppuun

kayttaja-3842 [14.01.2009 15:32:47]

#

Tervehdys,

Olen tässä tekemässä, kotiverkkooni tarkoitettua tiedostonsiirto softaa. Noh nytten olen siinä itse olennaisessa kohdassa, eli tiedoston lähetyksessä. Itse törmäsin nytten sellaseeseen ongelmaan, että miten saan tehtyä binary tiedoston sisällöstä yhden mega bitin kokoisia paketteja, joita sitten lähetän toiselle koneelle?

Onko se fstreamilla toteutettun luettava vain read funktiolla tähän tapaan.

read (muisti, 1024);

Metabolix [14.01.2009 15:39:18]

#

Laitahan nyt ensin termit kohdalleen. Tavussa on kahdeksan bittiä, haluatko nyt varmasti yhden megabitin (1/8 megatavua) vai ehkä sittenkin yhden megatavun? Lisäksi 1024 tavua tekee vasta kilon, mega on 1024 kiloa. (Ei nyt ruveta juttelemaan siitä, onko se 1024 vai 1000.)

Kyllä, voit read-funktiolla lukea haluamasi määrän. Muista avata tiedosto binaarimuodossa, ettei data hajoa.

Oliko jokin ongelmakin?

kayttaja-3842 [14.01.2009 16:01:05]

#

Joo siis elikkäs...

Yritän tehdä tuon nytten näin...

Hmm lukeekos tuo nytten tuosta read(memData, 1024) yhden kilotavun verran vai plajonkos.

   char memData[1024];

   ifstream inStream("testikuva.bmp", ios_base::in|ios_base::binary);

    if (!inStream.is_open()) return 1008; else{



   while( !inStream.eof() ){
     inStream.read(memData, 1024);

  send ( sd.fd, memData, sizeof(memData), 0 );

    inStream.seekg(1024, ios_base::cur);

  }
}
   inStream.close();

...jostain syystä tuo silmukakkaan ei lopu koskaan, lienetkö syy tuossa seekg kohdassa?

Grez [14.01.2009 16:09:07]

#

Aika outo tuo seek tuossa minun mielestäni. Siis haluatko tosiaan siirtää vain joka toisen kilotavun?

Metabolix [14.01.2009 16:13:56]

#

Lukee kilotavun. Sitten tuo seekg hyppää seuraavan kilotavun yli, eli lähetät vain puolet sisällöstä. Lisäksi viimeisellä kerralla lähetät mahdollisesti jotain ylimääräistäkin, jos tiedoston koko ei ole jaollinen 1024:llä.

#define KILOTAVU (1024)
#define MEGATAVU (1024 * 1024)

char buf[KILOTAVU];

while (s) {
  s.read(buf, sizeof(buf));
  send(sock, buf, s.gcount(), 0);
}

kayttaja-3842 [14.01.2009 16:15:01]

#

Mitenkä niin joka toisen??? :O

Eikös tuon pitäisi tehdä tuossa niin, että lukee ensiksi 1024 tavua, muuttujaan ja lähettää sen. Tämän jälkeen siirrytänä 1024 tavua seuraavaan kohtaan ja toistetaan niin pitää kunnes tavataan loppu. :P

Grez [14.01.2009 16:16:25]

#

Kyllä se read siirtää sitä lukupointteria ihan itse. Eli seekg:llä siirrät sitä toisen kerran, eli "hyppäät" yli seuraavasta kilotavusta. Voi olla että tuo seekg myös nollaa eof-bitin, jolloin loopin ikuisuus johtuisi juuri siitä.

kayttaja-3842 [14.01.2009 16:22:30]

#

Ahaa, joo niinpä tekeekin. Kiitos paljon. :)

kayttaja-3842 [14.01.2009 21:24:55]

#

Tulikin taas hieman probleemaa...


Eli olen tässä yrittänyt nytte kyhäillä sitä vastaan ottoa. Noh olen nytten saanut se ottamaan jotai dataa edes. Eli kokeilen nytten siirtää paintilla piirettyä kuvaa clientin kautta serverille. Noh kuva siirty, ainakin osittain. Meinaan alkuperäisen kuvan koko on 1 367 KB ja siiretyn kuvan koko on 1 326 ja tiedosto on korruptoitunut. Katsoin vähän tiedostonjen sisälle notepadilla ja sisällön alku merkit ovat ainakin täysin erilaiset.

...eli siis joku mättää! En tiedä onko vika lähetys päässä, vai vastaanotossa.

Lähetys tapahtuu tuolla Metabolixin esimerkkin lailla.

Eli näin

    char bufMem[1024];

  //Lähetetään serverille komento, että tiedonsiirto alkaa. :)
  send(sd.fd, "ALKAA!", sizeof("ALKAA!"), 0);

   ifstream s("testikuva.bmp", ios_base::binary);

while (s) {
s.read(bufMem, sizeof(bufMem));
send(sd.fd, bufMem, s.gcount(), 0);
}

 //Lähetetään serverille, että kaikki data on lähetetty
 send(sd.fd, "LOPPU!", sizeof("LOPPU!"), 0);

...ja sitten itse tuo tekemäni vastaan otto koodipätkä :D

while(loop){
  string data = "";
  bool suor = false;

     //Luodaan kirjotettava tiedosto
     ofstream so("testikuva2.bmp", ios_base::binary);

  //Hetaan data "data" muuttujaan
   data = Get(0);

   //Jos "suor" on true
    if( suor ){
     //Eli silmukka tiedoston siirron ajan... :)
     //Silmukka pyörii niin kauan, kunnes saa käsiinsä komennon "LOPPU!" jolloin "suor" muuttuu falseksi.
     while( suor ){
      data = Get(0);
       if( data == "LOPPU!" ) suor = false; else{
       so.write((char*)data.c_str(), data.length());
       cout << "[" << data << "]" << endl;
       }
     }

    }

    if( data == "ALKAA!"){
     cout << "OK!" << endl;
     suor = true;
    }

     //Tiedosto siiretty onnistuneesti suljetaan kirjoitus.
    if( data == "LOPPU!"){
     cout << "Tiedosto valmis!" << endl;
     suor = false;
     so.close();
    }
}

...koodit ovat hiukan outoja, mutta epätoivosena sitä joutuu kokeilemaan mitä päähän juolahtaa. :)

Metabolix [14.01.2009 21:37:06]

#

Jospa kirjoittaisit vastaanottokoodin uudestaan loogisemmin. Tuollaisenaan siitä ei ymmärrä pikaisella silmäyksellä yhtään mitään. Luultavasti olisi järkevää lähettää aloitusviestin mukana tiedoston koko, jotta voisit sitten lueskella sitä ihan rauhassa:

while (data = hae_rivi()) {
  istringstream ist(data);
  ist >> komento;
  if (komento == "tiedosto") {
    ist >> koko;
    for (i = 0; i < koko; i += data.length()) {
      data = hae_dataa(koko - i); // parametrina haluttu enimmäismäärä
      tiedosto.write(data.c_str(), data.length());
    }
  }
}

Nykyisessä koodissasi ensimmäinen datapaketti taitaa jäädä tallentamatta, kun luet dataa kahdessa kohdassa.

kayttaja-3842 [14.01.2009 22:34:20]

#

Tjoo, voisitko hieman selventää tuota sinun koodiasi?

Eli

while (data = hae_rivi()) { //Eli hae_rivi() funktio hakee käsittääkseni lähetetyt paketit?
  istringstream ist(data);
  ist >> komento; //Parsee lähetetyn kommennon viestistä ???
  if (komento == "tiedosto") {
    ist >> koko; //Parsee viestistä tiedoston koon? Tarkoitaako tämä siis koko tiedoston kokoa, eli minun tiedostoni koko on 1367KB eli koko muuttuja saa arvokseen 1399808, koska eikös tuo koko saada 1367*1024?
    for (i = 0; i < koko; i += data.length()) {
      //Onko tuo hae_dataa sitten jokin parseri vain, että se parsee esim substr:Llä tuosta "data" muuttujasta tietyn verran merkkejä?
      data = hae_dataa(koko - i); // parametrina haluttu enimmäismäärä //
      tiedosto.write(data.c_str(), data.length());
    }
  }
}

kayttaja-3842 [15.01.2009 10:56:19]

#

Toisin sanoen, voitiko hieman selventää vaikka nuo funktiot hae_dataa ja hae_rivi()?

kayttaja-3842 [15.01.2009 15:08:06]

#

Eli tässä olisi nytten tämä minun kokeiluni tuosta sinun esimerkistä? :P

Nytten tiedoston koko on kyllä oikea, mutta data on viallista.

if(suor){
    string data = "", komento = "";
    int koko = 0;


 ofstream so("testikuva2.bmp", ios_base::binary);

  while( suor ){
    data = Get(0);
  istringstream ist(data);
  ist >> komento;
  ist >> koko;
   if( komento == "tiedosto" ){
    cout << data << endl;

   if(data.length() > sizeof("tiedosto 1024"))
    data = data.substr(sizeof("tiedosto 1024"), data.length());

    for (int i = 0; i < koko; i += data.length()) {

      data = data.substr(0, koko - i);
      so.write(data.c_str(), data.length());
    }


   }
   if( komento == "" ){
    suor = false;
    cout << "Tiedosto siiretty!" << data << "]" << endl;
   }
}

 so.close();
}

Metabolix [15.01.2009 16:23:20]

#

Innostuin kirjoittamaan kokonaisen esimerkin. Tämä ainakin todistettavasti onnistui vaihtamaan itsensä kanssa oman lähdekoodinsa virheettömästi. Joudut tosin muokkaamaan koodia jonkin verran, että saat siitä oikeasti käytettävän. (Tässähän ei ole mitään hallintaliittymää, testissäkin suoritettu tiedostonsiirto vaati hieman eksoottisemman viritelmän, jotta saatiin kummallekin ohjelmayksilölle "palvelin". Tämä palvelin sitten käski toista ohjelmaa lue-komennolla.)

#include <sstream>
#include <fstream>
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

using namespace std;

// ei tarvitse koodiin osoitinmuunnoksia kirjoitella... ;)
// X *px = any_ptr(&mika_vain);
class any_ptr {
	void *ptr;
public:
	any_ptr(void *_ptr): ptr(_ptr) {}
	template <typename T> operator T* () { return (T*) ptr; }
};

int sock;
sockaddr_in addr = {0};

// lukee socketista dataa tietyn tavumäärän (odottaa, että tulee tarpeeksi)
string hae_dataa(int koko) {
	string rivi;
	char buf[1024];
	while (koko > sizeof(buf)) {
		recv(sock, buf, sizeof(buf), 0);
		rivi += string(buf, sizeof(buf));
		koko -= sizeof(buf);
	}
	recv(sock, buf, koko, 0);
	rivi += string(buf, koko);
	return rivi;
}

// lukee rivin dataa (tavu kerrallaan, kunnes tulee \n)
string hae_rivi() {
	string rivi;
	do {
		rivi += hae_dataa(1);
	} while (*rivi.rbegin() != '\n');
	return rivi;
}

// lähettää datan
void laheta_dataa(string data) {
	send(sock, data.c_str(), data.length(), 0);
}

// hoitaa kommunikaation
/**
 * lue koe.cpp
 *  - lukee pyydetyn tiedoston (esim. koe.cpp) ja lähettää tallenna-rivin
 * tallenna koe.cpp X
 *  - tätä riviä seuraa X tavua raakaa dataa
 * viesti Moi, Petteri!
 *  - tulostaa viestin vastapuolella
 * loppu
 *  - sulkee vastapuolen ohjelman
 * Data liikkuu muuten rivi kerrallaan (päättyy \n-merkkiin), mutta
 * tiedosto siirretään yhtenäisenä binaaripalikkana kesken kaiken.
 */
void kommunikoi() {
	string data, komento, viesti, nimi;
	fstream tiedosto;
	int koko, i;

	while (true) {
		// luetaan rivi dataa
		data = hae_rivi();
		istringstream ist(data);
		ist >> komento;
		if (komento == "lue") {
			// luetaan pyydetty tiedosto ja lähetetään
			ist >> nimi;
			tiedosto.open(nimi.c_str(), ios::in | ios::binary);

			// selvitetään koko
			tiedosto.seekg(0, ios::end);
			koko = tiedosto.tellg();
			tiedosto.seekg(0, ios::beg);

			// lähetetään otsikkorivi ("tallenna tiedostonimi koko")
			ostringstream ost;
			ost << "tallenna " << nimi << " " << koko << endl;
			laheta_dataa(ost.str());

			// lähetetään dataa 1024 tavun paketeissa
			char buf[1024];
			while (koko > sizeof(buf)) {
				tiedosto.read(buf, sizeof(buf));
				laheta_dataa(string(buf, sizeof(buf)));
				koko -= sizeof(buf);
			}
			tiedosto.read(buf, koko);
			laheta_dataa(string(buf, koko));

			// suljetaan tiedosto
			tiedosto.close();
		} else if (komento == "tallenna") {
			// vastaanotetaan tiedosto ja tallennetaan se
			ist >> nimi >> koko;
			tiedosto.open(nimi.c_str(), ios::out | ios::binary);
			tiedosto << hae_dataa(koko);
			tiedosto.close();
		} else if (komento == "viesti") {
			// tulee viesti; otetaan alusta välilyönti pois ja tulostetaan loput
			ist.get();
			getline(ist, viesti);
			cout << viesti << endl;
		} else if (komento == "loppu") {
			// vastataan samalla mitalla ja suljetaan ohjelma
			laheta_dataa(data);
			break;
		} else {
			// ilmoitetaan tuntemattomasta komennosta
			cout << "Virheellinen rivi: " << data;
		}
	}
}

int main(int argc, char **argv) {
	sock = socket(AF_INET, SOCK_STREAM, 0);
	addr.sin_family = AF_INET;
	// porttinumero: 1234x, x otetaan komentoriviparametrina
	addr.sin_port = htons(12340 + argv[1][0] - '0');
	inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
	connect(sock, any_ptr(&addr), sizeof(addr));

	kommunikoi();

	close(sock);
}

kayttaja-3842 [15.01.2009 17:15:47]

#

Kyllä, todella suuret kiitokset. :D Nytten se wörkkii niinkuin pitääkin.

kayttaja-3842 [26.01.2009 18:01:48]

#

Elikkäs olen taas tämän tiedonsiirto softan tiimoilla....


Eli nytten kun sain tehtyä tuon konsolipohjaisen "prototyypin", olen tässä väsäillyt GUI pohjaista tiedonsiirto softaa WinAPI:lla.

Olen nytten yrittänyt soveltaa tuota tiedoston siirtoa tuohon GUI:in, mutta vaikka minusta koodissa ei pitäisi olla mitään vikaa niin vika on silti.

Eli outoa on se, että siirrän 3kt kokoisen tekstitiedoston netinvälityksellä toiselle koneelle niin 3kt tiedosto siirtyy hienosti, mutta kun yritän siirtää 64kt kuvaa toiselle koneelle softa siirtää vain 6kt eli ei lähellekkään kaikkea.

Tässä alla on minun soveltamani tiedonsiirto funktio, mutta tosiaan se ei wörki. Koittakaa saada selkoa...

...koodissa on tosin aika paljon testiä varten väkerrettyä tavaa...

FD_WRITE:n sisältö

case FD_WRITE:

 while(true){

  if(!protocol.canSend){
   if( send(wParam, "", 1024, 0) == SOCKET_ERROR ){
      break;
   }
  }else{
    if(protocol.tSend(wParam) == 1200){
     break;
    }
  }



 }


break;

Lähetys funktio...

 int PROTOCOL::tSend(WPARAM wParam){
      char buf[1024];
      string numma = "";
       ostringstream ost;
       string pData = "";

 if(koko <= 0 && PROTOCOL::canSend){
   tiedosto.open("dd.bmp", ios::in | ios::binary);
            tiedosto.seekg(0, ios::end);
            koko = tiedosto.tellg();
            tiedosto.seekg(0, ios::beg);

   send(wParam, "Tallenna", sizeof(buf), 0);
   //MessageBox(NULL, strKoko.c_str(), "Koko", 0);
 }

  while( koko > sizeof(buf) ){
  tiedosto.read(buf, sizeof(buf));
  //sprintf(buf, "%d\n", koko);
  //numma = buf;

    if(send(wParam, buf, sizeof(buf), 0) == SOCKET_ERROR){
    // MessageBox(NULL, "Paina Send uudelleen!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
      tiedosto.seekg(kokoI, ios::beg);
      if (WSAGetLastError() == WSAEWOULDBLOCK){
       //ost << "Piste: " << tiedosto.tellg() << endl;
      // numma = ost.str();
       //MessageBox(NULL, numma.c_str(), "Ilmoitus", MB_OK|MB_ICONINFORMATION);
       return 1200;
      }else{
       MessageBox(NULL, "Joku virhe!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
      }
    }else{

     //sprintf(buf, "%d", koko);
     //MessageBox(NULL, buf, "Ilmoitus", MB_OK|MB_ICONINFORMATION);

     koko -= sizeof(buf);
     kokoI += sizeof(buf);
     //if(numma.substr(0, 4) == "1910") MessageBox(NULL, "Jummausta vaan!", "Jummaa!", 0);
    }
  }

  if(koko > 0 && koko < sizeof(buf) && PROTOCOL::canSend){
  tiedosto.seekg(kokoI, ios::beg);
  tiedosto.read(buf, koko);
  //sprintf(buf, "%d\n", koko);
    //sprintf(buf, "%d\n", koko);

  pData = string(buf, koko);

    if(send(wParam, pData.c_str(), sizeof(buf), 0) == SOCKET_ERROR){
     //return 1200;
      if (WSAGetLastError() == WSAEWOULDBLOCK){
       //MessageBox(NULL, "Paina Send uudelleen!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
       return 1200;
      }else{
       MessageBox(NULL, "Joku virhe!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
      }
    }else{

     tiedosto.close();
     PROTOCOL::canSend = false;
     koko -= sizeof(buf);
     kokoI += sizeof(buf);
     tiedosto.seekg(kokoI, ios::beg);
     sendOk = true;
    }
  }

  if(sendOk)
       if(send(wParam, "OK", sizeof(buf), 0) == SOCKET_ERROR){
      if (WSAGetLastError() == WSAEWOULDBLOCK){
       //MessageBox(NULL, "Paina Send uudelleen!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
       return 1200;
      }else{
       MessageBox(NULL, "Joku virhe!", "Ilmoitus", MB_OK|MB_ICONINFORMATION);
      }
      //return 1200;
      sendOk = false;
     }

  //send(pm.socket, "lopeta", sizeof(buf), 0);
      delete [] buf;

  return 1;
}

Metabolix [27.01.2009 08:10:24]

#

En edes jaksa lukea koodia niin tarkasti, että tuon virheen selvittäisin, kun tuo on niin sotkuista ja niin täynnä pikkuvirheitä, jotka voivat kaataa ohjelman tai aiheuttaa odottamattomia asioita. Tässä on niistä muutama:

Nämä löytyivät pikavilkaisulla minuutissa. Vastaavia muita periaatteellisia virheitä on varmasti kymmenkunta lisää, joten ajattelepa nyt kerran kunnolla läpi, mitä koodisi lähettää ja milloin.

kayttaja-3842 [27.01.2009 10:07:12]

#

Noh
Tuolle ns tyhjän lähettämiselle minulle on periaate, koska oman käsitykseni mukaan FD_WRITE:n ei päästä uudelleen ilman jos socketti ei palauta WSAEWOULDBLOCK virhettä. Joten jotta silmukka ei olisi ikuinen niin se on pakko lähettää dataa vaikka sitä ei tarviskaa niin pitää kunnes saadaan WSAEWOULDBLOCK ja breakataan. Sitten vasta päästään uudelleen FD_WRITEEN.

Eikös, se näin mene?

Mutta huomee se, että "tyhjän lähettämistä" ei tapahdu jos canSend on true, eli silloin vasta itse tiedostoa lähetetään.

Metabolix [27.01.2009 11:19:31]

#

Vaikka selityksesi tavallaan toimiikin, se ei muuta sitä tosiasiaa, että "":n lähettäminen 1024 tavun mittaisena on automaattisesti virhe. Katsopa huviksesi jollain ohjelmalla, mitä oikeasti tulee lähetettyä.

Muutenkin tuo on väärä periaate. Haluatko, että ohjelmasi käyttää jatkuvasti kaiken käytettävissä olevan kaistan? Oikea tapa on seuraava: Kun haluat lähettää dataa, lisäät sen lähetysjonoon (alla sendData-funktio). Kun lähetysjono kasvaa TAI saat FD_WRITE-viestin, yrität lähettää jonon alusta dataa sen verran, kuin on mahdollista (alla trySend-kutsut). Jos lähettäminen ei onnistu, odotat FD_WRITE-viestiä, ja jos onnistuu ja jono tyhjenee, mitään ei tarvitse tehdä ennen kuin lähetettävää tulee lisää.

Koodi on täysin hatusta vedetty, mutta ajatus käy toivottavasti selväksi.

/*
class PROTOCOL {
  private:
    std::deque<std::string> jono;
    int sock;
  public:
    void sendData(const char *data, int length);
    void sendData(std::string);
    void trySend();
};
*/
// Tehdään funktiot datan lähetykseen. Nämä lisäävät datan jonoon ja yrittävät lähettää jonosta dataa.
void PROTOCOL::sendData(const char *data, int length) {
  sendData(std::string(data, length));
}
void PROTOCOL::sendData(std::string data) {
  // Lisätään jonoon.
  jono.push_back(data);
  // Jono muuttui, yritetään lähettää.
  trySend();
}

// Funktio, joka yrittää lähettää dataa:
void PROTOCOL::trySend() {
  // Kun jonossa on lähetettävää
  while (!jono.empty()) {
    std::string data = jono.front();
    int length = data.length();
    int ret = send(sock, data.data(), data.size(), 0);
    if (ret == data.size()) {
      // Data meni, otetaan se pois jonosta ja jatketaan.
      jono.pop_front();
      continue;
    }
    ret = WSAGetLastError();
    if (ret == WSAEWOULDBLOCK) {
      // Data ei mennyt, lopetetaan yritys ja odotetaan FD_WRITE-viestiä.
      return;
    }
    if (ret == WSAEMSGSIZE) {
      // Viesti on liian iso, katkaistaan puoliksi ja laitetaan palat jonoon.
      jono.front() = data.substr(data.size() / 2);
      jono.push_front(data.substr(0, data.size() / 2));
    }
  }
}

// Lähetetään tekstiä:
protocol.send("OK\n");

// Viestin tullessa yritetään lähettää dataa. Funktio tietää, oliko lähetettävää ja menikö kaikki.
case FD_WRITE:
  protocol.trySend();
  break;

kayttaja-3842 [27.01.2009 11:54:20]

#

Hmm, joo o. Mutta sitä en vieläkään tajua, kuinka ajattelit päästä sinne FD_WRITE:n jos alussa ei olekkaan mitään lähetettävää dataa?

Eli ohjelman käynistyessään palauttaa FD_WRITEN:n, mutta kun alussa ei olekkaan mitään lähetettävää, niin trySend ei palauta missään vaihessa WSAEWOULDBLOCK:ia ja FD_WRITE:n ei palauteta enää.

Vai tarkoitatko, että hWnd:lle pitäisi itse lähettää tuo FD_WRITE SendMessage- funktiolla?

...eiku ei mitään sittenkää, ilmeisemmin se kutsutaan myös tuolla sendData:ssa. :)

Metabolix [27.01.2009 13:06:10]

#

Et määrittele funktiolle puskurin kokoa vaan datan määrän. Muista tämä. Jos siis laitat siihen 1024, niin lähetettävä määrä on todella 1024 tavua riippumatta siitä, käytätkö sen kokonaan vai lähetätkö tekstin "OK". Ne puuttuvat tavut otetaan muistista siitä kohti, mitä siellä sattuu "OK":n jälkeen tulemaan, ja tämä on virhe!

Et voi hallita paketteja tuolla tavalla, ja juuri siksi sinun täytyy tehdä, kuten edellisessä esimerkissäni esitin, eli ilmoittaa aina alussa, minkä kokoinen paketti on tulossa.

Kannattaa siis lisätä sendData-funktioon datan määrä

void PROTOCOL::sendData(std::string data) {
  char koko[16] = {0};
  sprintf(koko, "%08x", data.size());
  jono.push_back(koko); // koko heksana, esim 00001f00
  jono.push_back(data);
  trySend();
}

Vastaanotto tehdään vastaavalla tavalla, eli ensin luet kahdeksan merkin heksaluvun ja sitten sen kertoman määrän tavuja pakettia varten.

kayttaja-3842 [27.01.2009 14:10:36]

#

Joo o, mutta jos katos lähetän dataa vaikka

sendData("Moikka");

...niin nytten otan koon "Moikka" sanasta data.length():llä, mutta

nytten minun recv hakee silti 1024 tavua, niin eikös tämä ylimääränen data sitten ole "virheellistä"? Eli miten sen voi sitten hakea recv:llä oikein? Eli juuri tuon "Moikka" sanan verran? Jos lähetän sen "Moikka" sanan koon eka, niin eikös tapahdu silti tämä sama virhe, koska enhän voi tietää paljonko tuon lähetetyn koon tavu määrä on ja taas pädytään siihen, että recv hakee liian paljon dataa.

Metabolix [27.01.2009 16:01:20]

#

Mutta nythän nimenomaan tiedät koon tavumäärän: binaarina se olisi sizeof(int), heksaluvuksi tulostettuna 8 merkkiä (32-bittisillä luvuilla).

Itse tekisin rajapinnan, joka läpinäkyvästi lähettää ja vastaanottaa kokonaisia paketteja tällä mekanismilla ja jolta sitten voi pyytää aina seuraavan paketin.

kayttaja-3842 [27.01.2009 16:11:08]

#

Voisiko olla mahdollista, että string tyyppinen muuttuja kadottaisi binary datan? Itsellä siirtää nytten hienosti tekstiä sisältävää dataa, mutta binary filut ei siirry oikein.

Avaan kyllä tiedosto binary tilassa.

kayttaja-3842 [27.01.2009 18:36:24]

#

Nytten kaikki toimii niikuin pitää, kiitos paljon.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta