Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Socket i OutOfMemory greska

[es] :: .NET :: Socket i OutOfMemory greska

[ Pregleda: 1519 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Bope

Član broj: 62233
Poruke: 291
*.adsl.verat.net.

Sajt: www.shortsms.me


+4 Profil

icon Socket i OutOfMemory greska02.07.2011. u 16:52 - pre 155 meseci
Imam veliki problem. Pravim aplikaciju koja treba da se sastoji od serveskog i klijentskog dela. Ta dva dela trebaju da komuniciraju nekako, da razmenjuju objekte. Odlucio sam se da koristim socket-e zato sto sam ih i ranije koristio i zato sto mogu bez problema da testiram aplikaciju na svom kompu (pokrenem i serverski i klijentski deo i dam im da slusaju port na 127.0.0.1).

E sad, kada sa sa klijentskog dela pokusam da serverskom delu prosledim neki "custom" objekat (koji moze da se serijalizuje, naravno), na serverskom delu dobijem "OutOfMemory" gresku! Citao sam clanke na drugim sajtovima, kopirao kod, ali nikako mi nije jasno gde gresim.

Test klasa koja je definisana i u klijentskom i u serverskom kodu:

Code:
[Serializable]
        class Boza
        {
            public string poruka="default";
        }


kod za slanje (nalazi se u klijentskom delu programa):
Code:

private void cmdSendData_Click(object sender, System.EventArgs e)
        {
            try
            {
                Boza boza = new Boza();

                NetworkStream ns = new NetworkStream(m_socWorker); //m_socWorker je Socket
                BinaryWriter bw = new BinaryWriter(ns);

                MemoryStream ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, boza);

                bw.Write(ms.ToArray());
                MessageBox.Show("Duzina: " + ms.ToArray().Length); //duzina je 152!
                ns.Close();
            }
            catch(System.Net.Sockets.SocketException se)
            {
                MessageBox.Show (se.Message );
            }
        }


gornji kod radi bez problema. Kod serverskog dela za prijem podataka (kod koji i pravi probleme):
Code:

public  void OnDataReceived(IAsyncResult asyn)
        {
            try
            {
                CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;

                NetworkStream ns = new NetworkStream(m_socWorker);
                byte[] buffer = new byte[1024];
                ns.Read(buffer, 0, buffer.Length);
                
                BinaryFormatter bin = new BinaryFormatter();
                MemoryStream mem = new MemoryStream(buffer.Length);

                mem.Write(buffer, 0, buffer.Length);
                mem.Seek(0, SeekOrigin.Begin);
                Boza boz = (Boza)bin.Deserialize(mem); //OVDE SE JAVLJA GRESKA!

                MessageBox.Show(boz.poruka);

                theSockId.thisSocket.EndReceive(asyn);

                WaitForData(m_socWorker);
            }
            catch (ObjectDisposedException )
            {
                System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
            }
            catch(SocketException se)
            {
                MessageBox.Show (se.Message );
            }
        }


Greska se javlja prilikom pokusaja deserijalizacije. Gde gresim? Gde je problem u kodu?
 
Odgovor na temu

vujkev
Beograd

Član broj: 8072
Poruke: 1347
*.dynamic.isp.telekom.rs.



+104 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 08:39 - pre 155 meseci
na prvi pogled

prilikom primanja praviš buffer od 1024 bajta i to pokušavaš da deserijalizuješ. Pošto šalješ samo 152 bajta možda ti to pravi problem


usput, zato ne koristiš WCF za klijent-server komunikaciju. Mislim da će ti biti mnogo lakše


Naučio sam...
Da je važnije biti ljubazan nego biti u pravu
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12850



+4784 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 10:37 - pre 155 meseci
Ne znam da li je do toga sto je pomenuo vujkev, ali to svakako treba ispraviti.
ns.Read() ce ti vratiti koliko je bajtova zaista procitano. Ti si mu dao niz i podatak koliko maksimalno moze, ali ako je manje stiglo, u niz ce biti upisano to sto je stiglo a bice vraceno koliko je to.
Taj broj koristi za kreiranje MemoryStream-a i kopiraj samo taj deo u njega. Znaci, nesto kao:

Code (csharp):

int BytesRead = ns.Read(buffer, 0, buffer.Length);
               
BinaryFormatter bin = new BinaryFormatter();
MemoryStream mem = new MemoryStream(BytesRead);

mem.Write(buffer, 0, BytesRead);
 

 
Odgovor na temu

Bope

Član broj: 62233
Poruke: 291
*.adsl.verat.net.

Sajt: www.shortsms.me


+4 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 12:58 - pre 155 meseci
Interesantno, mada sada dobijam gresku "End of Stream encountered before parsing was completed.". To je ipak neki pomak :)

Sto se WCF-a tice vec sam poceo da citam knjigu. I na drugim mestima po netu sam saznao da je WCF bolji jer se njime zaobilazi "plumbing" programiranje. Jedini problem koji sam ja imao je taj sto je moj kod bio pisan u net 2.0 pa nisam ni znao za WCF :P :)))
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12850



+4784 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 13:01 - pre 155 meseci
U debug-u proveri sta je u nizu, deluje kao da fali deo (stigao je do kraja a nije uspeo da zavrsi parsiranje, a jedino sto mi trenutno pada na pamet zasto nije zavrsio je da nije imao sve sto mu treba).

Sto se WCF-a tice, ako ti nisu performanse top-priority mozes ga kristiti i bice ti mnogo lakse.
 
Odgovor na temu

Bope

Član broj: 62233
Poruke: 291
*.adsl.verat.net.

Sajt: www.shortsms.me


+4 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 13:12 - pre 155 meseci
Opet su problem performanse? Bas indikativno - svaka tehnologija koja olaksava umanjuje performanse (linq, entity sad i wcf) :)))
Moracu samo da proverim koliki je taj pad performansi, ne znam kako bi se sve to ponasalo kada stavim na pravi server na kome bi aplikaciju koristilo vise ljudi odjednom...
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12850



+4784 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 13:28 - pre 155 meseci
Nisu problem, ali svaka od tih tehnologija je opstije namene nego sto je tvoja konkretna potreba. Zato su bolje performanse kada pravis nesto tako da sadrzi samo ono sto ti treba nego kada imas sloj apstrakcije koji je uopsteniji. Medjutim, u velikom broju slucajeva ta razlika je nebitna pa se onda koristi ono sto ubrzava i/ili olaksava razvoj aplikacije. Zbog toga se te stvari i prave inace bismo jos uvek radili u masinskom kodu :)
 
Odgovor na temu

Bope

Član broj: 62233
Poruke: 291
*.adsl.verat.net.

Sajt: www.shortsms.me


+4 Profil

icon Re: Socket i OutOfMemory greska03.07.2011. u 13:40 - pre 155 meseci
Naravno :) Ok, pogledacu taj ECF kapiram da nije nesto komplikovan pa ce valjda da mi ustedi zivce :)

P.S. sto se tice koda, ni promena koju si predlozio nije urodila plodom, opet se javlja OutOfMemory. Debug je pokazao da deserijalizacija stigne do 107-og elementa niza (memorystream position je na 107 od 151) i tada se javi greska.

[Ovu poruku je menjao Bope dana 03.07.2011. u 16:25 GMT+1]
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Socket i OutOfMemory greska04.07.2011. u 09:08 - pre 155 meseci
Ono što je vujkev rekao ne važi, svakako da ćeš napraviti dovoljno veliki bafer (1KiB je čak premalo, moja preporuka je 64, osim ako ne planiraš više od 1000 konkurentnih klijenata ). Kad god radiš sa streamovima (Read i Write) koristi koliko je zaista bajtova pročitano/zapisano, kao što je Shadowed rekao. Što se tiče konkretnog problema bez nekog sample projekta ne znam šta bi moglo da bude, ali uopšteno, zašto koristiš sockete direktno? Probaj sa TcpClient i TcpListener klasama (imaš dobar example na MSDN-u), one lepo wrappuju sockete za 90% slučajeva. I probaj da uradiš deserijalizaciju na klijentu pre slanja, da vidiš da li je problem u tome ili u mrežnom protokolu.

@Shadowed- "Zbog toga se te stvari i prave inace bismo jos uvek radili u masinskom kodu" - Ovo ide na zid radne sobe
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

vujkev
Beograd

Član broj: 8072
Poruke: 1347
*.dynamic.isp.telekom.rs.



+104 Profil

icon Re: Socket i OutOfMemory greska04.07.2011. u 10:53 - pre 155 meseci
Nisam rekao da ne napravi dovoljno veliki buffer da primi podatak, nego da deserijalizuje samo onoliki buffer koji je poslao. U svakom slučaju probao sam da li će deserijalozivati i veći buffer nego što je poslato i to radi, tako da to nije greška

Jedini mogući problem koji ostaje je greška u slanju


Inače ovo
Code:
                
                BinaryFormatter bin = new BinaryFormatter();
                MemoryStream mem = new MemoryStream(buffer.Length);

                mem.Write(buffer, 0, buffer.Length);
                mem.Seek(0, SeekOrigin.Begin);
                Boza boz = (Boza)bin.Deserialize(mem); //OVDE SE JAVLJA GRESKA!




može da se zameni sa
Code:
                
                BinaryFormatter bin = new BinaryFormatter();
                MemoryStream mem = new MemoryStream(buffer);

                Boza boz = (Boza)bin.Deserialize(mem);


memoryStream inicijalizuješ sa samim bufferom sa kojim treba da ga napuniš. Dva linije manje koda, a pretpostavljam i da je brže
Naučio sam...
Da je važnije biti ljubazan nego biti u pravu
 
Odgovor na temu

Bope

Član broj: 62233
Poruke: 291
*.adsl.verat.net.

Sajt: www.shortsms.me


+4 Profil

icon Re: Socket i OutOfMemory greska04.07.2011. u 11:53 - pre 155 meseci
Vidis, "TcpListener" mi nije pao na pamet, ali ne znam vise koliko je to bitno jer sam gledao neke video tutorijale za WCF i ono zaista nije tesko! Deluje mnogo lakse od ovog petljanja sa soketima :)
 
Odgovor na temu

[es] :: .NET :: Socket i OutOfMemory greska

[ Pregleda: 1519 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.