Dela upp en Byte[] i flera små för att skicka via UDP?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Okej, för just nu kör jag en liten fuling.

if (u.Length / 100 < 60000)
{
size = u.Length / 100;
}
else if (u.Length / 50 < 60000)
{
size = u.Length / 50;
}
else if (u.Length / 25 < 60000)
{
size = u.Length / 25;
}

Typ såna grejer, men vill ju hellre ha något som typ.

(Gör så litet som det går)
så den kan byta från 1 paket till 200 och hej vilt, beroende på vad som är lägst för den storleken.

Det skall dock inte behövas; sätt den till 1400 eller så och hoppas på det bästa.

Skrivet av Zero Walker:

Fixade buggen, va var det för fel?
för fungerar utmärkt före och efter?

Den innebar att det sista paketet (om <total storlek>/size inte gick jämt upp) hamnade 2*(antal paket -1) byte för långt bak i databyte. Hur det visar sig i praktiken beror förmodligen på vilken bildkodning man har: kanske några svarta pixlar, kanske suddiga områden eller kanske en helt ogiltig bild.

Permalänk

Okej nice, suveränt.
Men finns det något vettigt sätt att räkna ut om ett paket är snabbare för mig än flera små (ofragmenterade)?
För kan inte direkt kolla och se skillnaden bara sådär verkar det som.

Ah, kanske var det som gav en vit linje längst ner på bilden som kunde fladdra lite, den var typ 1-2 pixlar hög och längden i bred.
för verkar inte få det nu tror jag.

EDIT:

Har stött på ett litet problem.

Additional information: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
i += data.Length-2;

Tror det är att filen blir för stor, för testade ändra min komprimering till LZ4, så det ser ut så här:

pictureBox1.BackgroundImage = byteArrayToImage(Lz4.DecompressBytes(databyte)); byte[] u = Lz4.CompressBytes(imageToByteArray(holder), Lz4Mode.Fast);

Bilden är då BMP såklart, för annars förlorar jag ju på det.

Hmm, verkar löst sig när ja öka storleken på databyte. Är det möjligt att göra databyte oändlig/dynamisk?
För den behöver ju egentligen inte ha en fast storlek.

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Är det möjligt att göra databyte oändlig/dynamisk?
För den behöver ju egentligen inte ha en fast storlek.

Jadå, men då får man skicka med även hur stor den skall vara. Jag passar även på att tillåta upp till 65536 paket:

int c = 0; int size = 1400; var buff = new byte[size + 8]; UInt16 n = 0; UInt16 N = (UInt16)Math.Ceiling(u.Length / (float)size); byte[] ss = BitConverter.GetBytes(u.Length); for (int i = 0; i < u.Length; i += size) { c = Math.Min(size, u.Length - i); buff[0] = (byte)(n / 256); buff[1] = (byte)(n++ % 256); buff[2] = (byte)(N / 256); buff[3] = (byte)(N % 256); Array.Copy(ss, 0, buff, 4, 4); Array.Copy(u, i, buff, 8, c); udpcap.Send(buff, c + 8, adress.Address.ToString(), 1700); }

databyte = new byte[1]; int i = 0, j = 0; UInt16 n, N; int size; while (true) { byte[] data = udpcap.Receive(ref adress); n = (UInt16)(256 * data[0] + data[1]); N = (UInt16)(256 * data[2] + data[3]); size = BitConverter.ToInt32(data, 4); if (databyte.Length != size) databyte = new byte[size]; if (n == 0) { i = 0; j = 0; } if (n != N - 1 && j < N - 1) { Array.Copy(data, 8, databyte, n * (data.Length - 8), data.Length - 8); i += data.Length - 8; ++j; } else if (j == N - 1 && n == N - 1) { Array.Copy(data, 8, databyte, i, data.Length - 8); pictureBox1.BackgroundImage = byteArrayToImage(databyte); } else break; }

Permalänk

Suveränt, tjänar man på det?
tänker eftersom man måste skicka ett extra paket med info så kanske man förlorar på det i ren hastighet?

För är ute att göra det som ska göras, så snabbt som möjligt, alla milisekunder räknas.

EDIT:

Hmm den verkar fungera delvis, men tappar bilden väldigt ofta och är betydligt slöare tyvärr.
Men kanske blir mer risk när man ska ha ett paket som sätter storleken, eller?

Tack

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Suveränt, tjänar man på det?
tänker eftersom man måste skicka ett extra paket med info så kanske man förlorar på det i ren hastighet?

Nja, det blir ju bara fyra (sex om man även räknar de större räknarna) byte mindre data per paket än förut, så så mycket extra blir det inte.

Skrivet av Zero Walker:

Hmm den verkar fungera delvis, men tappar bilden väldigt ofta och är betydligt slöare tyvärr.
Men kanske blir mer risk när man ska ha ett paket som sätter storleken, eller?

Även om man sätter size till samma som förut? Och utan komprimering och liknande? Skillnaden borde inte vara särskilt stor.
Det kan också hjälpa att öka storleken på sändnings- och mottagningsbuffertar. Till exempel:

udpcap.Client.SendBufferSize *= 16; udpcap.Client.ReceiveBufferSize *= 16;

Om adress är en IPEndPoint kan det också vara effektivare att använda

udpcap.Send(buff, c + 8, adress);

Skrivet av Zero Walker:

Bilden är då BMP såklart, för annars förlorar jag ju på det.

Png kan kanske annars vara ett alternativ?

Permalänk

Ska testa att ändra senare, och se om det funkar.

Adress är från en text ruta där ja skriver IP Adressen "213.12.123.123" typ.

BMP är snabbast såklart, och ja komprimmerar sen BMP med LZ4 för den ska vara jäkligt snabb.
Om ja skulle köra PNG rakt på istället, skulle det gå för sakta, PNG är jäkligt slött tyvärr.

Vill gärna testa på libjpeg-turbo. Men vet inte hur man använder det i c#, du råkar inte veta något om det?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Vill gärna testa på libjpeg-turbo. Men vet inte hur man använder det i c#, du råkar inte veta något om det?

Nej, det har jag inte testat, men man kan även höja kvaliteten på den inbyggda jpeg-kodningen: http://stackoverflow.com/a/8703634 . Helt skarpt blir det dock inte.

Permalänk

Det verkar funka nu.

Men undrar, vad är den riktiga skillnaden från att ha en dynamisk byte array, från att sätta en enorm?
Tänker, tjänar man på det prestanda vis, eller är det bara med struktur att göra?

och när det kommer till buffern, vad gör den, för vill minska latencyn så mycket som det bara går, så vill inte ha någon hög buffer om det fungerar som ja tror det gör.

Och jo vet om inbyggda, men tror libjpeg lär vara betydligt snabbare och förmodligen bättre än windows egna.
iaf får ja det från det jag läst. Men vet inte om den är bunden till c++ eller nåt.

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Men undrar, vad är den riktiga skillnaden från att ha en dynamisk byte array, från att sätta en enorm?
Tänker, tjänar man på det prestanda vis, eller är det bara med struktur att göra?

Nackdelen med att ha en enorm är främst att den tar mycket minne som sannolikt aldrig kommer att användas (samtidigt som det kan vara svårt att verkligen vara säker på att man aldrig kommer behöva mer utrymme). En dynamisk löser detta, men å andra sidan kan det kosta lite mera att skapa nya buffertar varje gång storleken ändras. Förmodligen är dock kostnaden försumbar om man jämför med till exempel tiden som nätverksöverföringen kräver.

Skrivet av Zero Walker:

och när det kommer till buffern, vad gör den, för vill minska latencyn så mycket som det bara går, så vill inte ha någon hög buffer om det fungerar som ja tror det gör.

Jag tror inte att någon sådan effekt är märkbar, men testa gärna olika värden. Dock ger en liten buffert högre risk för tappade paket.

Permalänk

Okej det låter vettigt.

Hmm, när du säger tappade paket ökning, gills det också i LAN scenarion?

EDIT:

Verkar som det, kan ja räkna ut om ja tappar, så ja kan försöka mig fram att få så låg som möjligt?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Hmm, när du säger tappade paket ökning, gills det också i LAN scenarion?

Ja (själv har jag bara testat med sändare och mottagare på samma dator och det händer även då).

Skrivet av Zero Walker:

Verkar som det, kan ja räkna ut om ja tappar, så ja kan försöka mig fram att få så låg som möjligt?

Glöm inte att experimentera också. Mät hur lång tid överföringen tar för olika värden; kanske är inte minst bäst?

Permalänk

Jo är det ja testat också.
Testade nyligen med en laptop, och då jäklar va det laggar, funkar prima på min dator när ja kör på min IP (alltså inte 127.0.0.1), men använder ja en annan dator så verkar det inte funka lika väl.

Hmm, vet inte va det kan bero på, om det är UDP i sjävl som strular till det, eller något annat.

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Testade nyligen med en laptop, och då jäklar va det laggar, funkar prima på min dator när ja kör på min IP (alltså inte 127.0.0.1), men använder ja en annan dator så verkar det inte funka lika väl.

Det blir ju snabbt en hel del data som skall överföras också; hur ser det ut i aktivitetshanteraren?

Permalänk

Jo vet, men verkar som jag var lite för optimistisk om min laptop.
CPU och fläkten drar igång rejält och hela datorn slutar typ fungera, så är rätt värdelöst att testa med den.
Är klart prestandan som får det att hänga efter och inte nätverket i det här fallet.

På tal om prestanda, du vet inte om något bättre sätt att visa bild på bild än att anvädna picturebox?
Tänkte om man kunde ha något som gick på grafikkortet, typ renderings fönster, som man bara spammar på alla bilder som kommer in på?
För tror knappast en picturebox är menat att uppdateras kosntant som en film.

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

CPU och fläkten drar igång rejält och hela datorn slutar typ fungera, så är rätt värdelöst att testa med den.

Kan det vara komprimeringen tro? Fungerar jpeg bättre?

Permalänk

Tror det var jpeg ja testa. Men den laptopen är extrem fall.
På min dator kan det ta 4% och på den är det typ 70%.

Är någon extremt gammal singel kärnig CPU i den.

Men lär vara dekomprimeringen som slår ut den, möjligen också sättet ja använder picturebox, tror inte det är särskilt optimalt att uppdatera bilden hela tiden med den.

Permalänk

Juste, Om ja skulle vilja skicka via TCP hur gör jag då?
För har aldrig förstått mig på det.

Vet att man måste connecta först, vilket jag försökt, och sen att den ska lyssna och accepta clienten.
Men det verkar inte funka för mig, så antar att det är någonting jag missat?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Juste, Om ja skulle vilja skicka via TCP hur gör jag då?
För har aldrig förstått mig på det.

Vet att man måste connecta först, vilket jag försökt, och sen att den ska lyssna och accepta clienten.
Men det verkar inte funka för mig, så antar att det är någonting jag missat?

I server-änden har man lämpligen en TcpListener som väntar på nya anslutningar:

System.Net.Sockets.TcpListener l = new System.Net.Sockets.TcpListener(1800); l.Start(); System.Net.Sockets.TcpClient t1 = l.AcceptTcpClient();

och klienten ansluter genom

System.Net.Sockets.TcpClient t2 = new System.Net.Sockets.TcpClient(); t2.Connect("127.0.0.1", 1800);

När anslutningen väl är upprättad kan man till exemel skriva till t1.GetStream() och läsa från t2.GetStream() för att skicka data från server till klient. Enklast är det med den inbyggda serialiseringen, men det går inte alltid så fort:

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); b.Serialize(t1.GetStream(), u);

respektive

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); byte[] u = (byte[])b.Deserialize(t2.GetStream();

Ovanstående kommandon blockerar typiskt de aktiva trådarna, så man vill förmodligen ha flera sådana. Annars finns asynkrona alternativ.

Permalänk

Tcplisten har inte GetStream för mig;S

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Tcplisten har inte GetStream för mig;S

Nej, det skall vara en TcpClient (som man till exempel får från TcpListener.AcceptTcpClient()).

Permalänk

Ah såg nu, den skapar alltså en ny client när den får en uppkoppling?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Ah såg nu, den skapar alltså en ny client när den får en uppkoppling?

Ja. På så sätt kan till exempel samma TcpListener användas för att ansluta många klienter.

Permalänk

Okej har skrivit så här och det går lite som det går.

private void Listen() { System.Net.Sockets.TcpClient tt1 = tcplisten.AcceptTcpClient(); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); while (checkBox1.Checked) { byte[] u = (byte[])b.Deserialize(tt1.GetStream()); ms = new MemoryStream(u); pictureBox1.BackgroundImage = Image.FromStream(ms); } }

private void Send() { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); while (capcon == true) { if (tcpcap.Connected) { byte[] u = imageToByteArray(PrintWindow("Application")); b.Serialize(tcpcap.GetStream(), u); } else { tcpcap.Connect("127.0.0.1", 1700); } }

Permalänk
Hedersmedlem

Vad händer?

Permalänk

Varierar beroende på vilken ja startar först, Recieve eller Send.
På Recieve får jag:

Additional information: Object reference not set to an instance of an object.
System.Net.Sockets.TcpClient tt1 = tcplisten.AcceptTcpClient();

Vilket jag inte direkt förstår, då ja har satt den ett värde och det.

Startar ja Send först får jag:

Additional information: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.

Det kan dock komma utifrån hur ja satt IP Adresserna, så tror inte det är något riktigt problem, problemet ligger nog i det förstnämnda.
b.Serialize(tcpcap.GetStream(), u);

EDIT:

Kanske fått igång det, hade satt Tcplisten två gånger, så ändrade det, verkar fungera:)

Permalänk

Yes funkar helt klart, äntligen har jag lyckats att använda TCP överhuvudtaget, man tackar så mycket, försökt i flera dagar utan någon nytta:)

Men undrar, TCP fungerar väl så här typ.

TCP client - > skickar paket - > TCP Server tar emot - > skickar bekräftelse till TCP Client.

Vilket med andra ord leder till 50% högre latency om ja tänker rätt?

UDP däremot, skickar bara på och på, sen hur det kommer fram struntar den i.
Men tack vare det har den 50% lägre latency för den bekräftar ingenting alls.

Det ja kör nu från dig är väl att man strukturerat UDP att fungera som TCP?
Man har markerat paket och den säger nej om alla inte kommer fram, eller?

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Men undrar, TCP fungerar väl så här typ.

TCP client - > skickar paket - > TCP Server tar emot - > skickar bekräftelse till TCP Client.

Vilket med andra ord leder till 50% högre latency om ja tänker rätt?

Riktigt så illa är det dock inte. Protokollet tillåter att paket skickas även om föregående ännu inte har bekräftats och flera paket kan bekräftas på samma gång. Däremot kommer paket som inte bekräftas förr eller senare sändas om, vilket kanske inte är önskvärt om man är mera intresserad av att ny information överförs snabbt än att inaktuell information verkligen kommer fram.

Skrivet av Zero Walker:

Man har markerat paket och den säger nej om alla inte kommer fram, eller?

Den kontrollerar i alla fall att rätt antal paket har mottagits. Sedan skulle man till exempel ha tappat ett paket och fått en extra kopia av ett annat, men det är kanske inte så sannolikt.

Permalänk
Citat:

Däremot kommer paket som inte bekräftas förr eller senare sändas om, vilket kanske inte är önskvärt om man är mera intresserad av att ny information överförs snabbt än att inaktuell information verkligen kommer fram.

Är det ja skulle vilja förhindra.
Ja är intresserad av att skicka så snabbt som möjligt.

Ja kan lätt klara mig på korrumperade bilder då och då.
Men tyvärr verkar det mer bli, ingen bild alls, för den kan inte äns få fram att set ska vara en bild om ja förstår rätt.

Citat:

Den kontrollerar i alla fall att rätt antal paket har mottagits. Sedan skulle man till exempel ha tappat ett paket och fått en extra kopia av ett annat, men det är kanske inte så sannolikt.

Ah okej.

Men underligt då att den funktionen verkar vara slöare en TCP funktionen ja testa nu, ska det vara så?
Tänker TCP vill ju bekräfta att allting kommer punkt och pricka.

Men din UDP funktion säger bara, oj 10paket har kommit, och vi ska ha 10, bra vi fortsätter.

Permalänk
Hedersmedlem
Skrivet av Zero Walker:

Men underligt då att den funktionen verkar vara slöare en TCP funktionen ja testa nu, ska det vara så?
Tänker TCP vill ju bekräfta att allting kommer punkt och pricka.

Tcp försöker också anpassa sig till vilka förhållanden som råder; till exempel kan nog fler än 1500 byte sändas per paket om det verkar fungera.

Permalänk

I see, kanske har den mer att ge än ja trott.
För den fungerar jäkligt bra med NoDelay aktiverat, annars är den rätt seg märkte jag.

Däremot om filerna blir stora hamnar allt efter väldigt mycket, och det är inte nätverket som säger ifrån.

Jag är inte hundra på vad det är faktiskt.

Men, du nämnde att BinaryFormatter inte va särskilt snabb i alla dagar eller hur?

Ja försökte leta omkring om alternativ, och kom då över Protobuf som verkar vara det Google kör på, och NetSerializer.
http://code.google.com/p/protobuf/
https://github.com/tomba/netserializer
Men när ja använder dom, verkar det inte fungera, vet inte varför, men också vet ja inte hur det skiljer sig mellan dom, så kanske man måste ställa in eller liknande.