C# - NetworkStream - Posílání souboru/obrázku – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C# - NetworkStream - Posílání souboru/obrázku – .NET – Fórum – Programujte.comC# - NetworkStream - Posílání souboru/obrázku – .NET – Fórum – Programujte.com

 

NemeK0
Duch
20. 2. 2011   #1
-
0
-

Zdravím, potřeboval bych pomoc.
Chci udělat přenos souboru nebo rovnou obrázku. Mám server a klient, klient je vždy jen jeden. Server má poslat klientovi obrázek.
Má to být přes NetworkStream, protože takto už mám udělaný dejme tomu chat.

Server:

byte[] bStream = ImageToByte(NewBitmap);

networkStream.Write(bStream, 0, bStream.Length);
networkStream.Flush();

Funkce ImageToByte:
static byte[] ImageToByte(System.Drawing.Image iImage)

{
MemoryStream mMemoryStream = new MemoryStream();
iImage.Save(mMemoryStream,
System.Drawing.Imaging.ImageFormat.Gif);
return mMemoryStream.ToArray();
}

Klient:
byte[] bytesFrom = new byte[100025];


while (true)
{
serverStream = clientSocket.GetStream();
serverStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);

//System.Drawing.Image screen = System.Drawing.Image.FromStream(serverStream);
//Screen_Box.Image = screen;
}

Jde o to, že obrázek přijde po částech, já ho taky čtu po částech, ale musím nějak zkontrolovat že je ten obrázek kompletní a už ho převést na obrázek! Zkusil jsem serverem ihned po poslání obrázku poslat další zprávu, že je obrázek kompletní, jenomže žádná taková zpráva klientovi nedojde!

Nahlásit jako SPAM
IP: 77.48.59.–
nervak0
Věrný člen
21. 2. 2011   #2
-
0
-

Před daty si pošli jejich délku.

Nahlásit jako SPAM
IP: 213.211.51.–
NemeK0
Duch
21. 2. 2011   #3
-
0
-

Díky, to mě nenapadlo,
tak jsem to vyzkoušel, a celková délka dat co dojdou je vždy o něco vyšší než to co jsem poslal :( a opravdu nepočítám délku dat té informace o délce dat.

Server:

byte[] Image_Bytes = ImageToByte(NewBitmap);

byte[] Length_Bytes = BitConverter.GetBytes(Image_Bytes.Length);
byte[] Length_Signal_Bytes = System.Text.Encoding.UTF8.GetBytes("BYTESLENGTHSIGNAL");
byte[] Length_Send_Bytes = new byte[Length_Signal_Bytes.Length + Length_Bytes.Length];

Length_Signal_Bytes.CopyTo(Length_Send_Bytes, 0);
Length_Bytes.CopyTo(Length_Send_Bytes, Length_Signal_Bytes.Length);

networkStream.Write(Length_Send_Bytes, 0, Length_Send_Bytes.Length);
networkStream.Flush();

networkStream.Write(Image_Bytes, 0, Image_Bytes.Length);
networkStream.Flush();

Klient:
byte[] bytesFrom;

int length;
string message;
int Delka_Dat = -1;
int Prijmuta_Delka = 0;

while (Connected)
{
try
{
serverStream = clientSocket.GetStream();
length = (int)clientSocket.ReceiveBufferSize;
bytesFrom = new byte[length];
serverStream.Read(bytesFrom, 0, length);

message = System.Text.Encoding.UTF8.GetString(bytesFrom);
if (message.Contains("BYTESLENGTHSIGNAL"))
{
Delka_Dat = (BitConverter.ToInt32(bytesFrom, 17));
}
else
{
Prijmuta_Delka += length;
//MessageBox.Show("Přijámám skutečná data! Celková délka je "+Prijmuta_Delka.ToString()+" / "+Delka_Dat.ToString()+"; Data: "+message);
if (Prijmuta_Delka >= Delka_Dat)
{
MessageBox.Show("Obrázek je kompletní! "+Prijmuta_Delka.ToString()+" / "+Delka_Dat.ToString());
// tu se to objeví tak 2x a po každé je to o něco málo vyšší než max :( problém je v tom že se to klidně zobrazí víckrát, takže už když se to zobrazí poprvé si budu myslet že je to kompletní a není...
}
}
}
catch { }
}

Nahlásit jako SPAM
IP: 77.48.59.–
nervak0
Věrný člen
22. 2. 2011   #4
-
0
-

1. čteš pořád stejně velký blok.
2. nekontroluješ, kolik jsi opravdu načetl.
3. co když BYTESLENGTHSIGNAL nenačteš najednou? co ta data před ním? co když za ním bude méně nebo více dat, než ty 4B s délkou? proč se testuje každý načtený blok.
5. po kompletním načtení zůstáváš v tom cyklu.

Některé z těch věcí možná nevadí, záleží na tom, jak to máš napsané.

//byte[] data = ImageToBytes(img);

//NetworkStream ns = new NetworkStream(sock);

ns.Write(Int32ToBytes(data.Length), 0, 4);
ns.Write(data, 0, data.Length);
ns.Flush();
//byte[] buf = new byte[20 * 4096];

//NetworkStream ns = new NetworkStream(sock);

if (ns.Read(buf, 0, 4) == 4) {
int size = BytesToInt32(buf);
MemoryStream ms = new MemoryStream(size);
while (size > 0) {
int sz = (size > buf.Length) ? buf.Length : size;
int rd = ns.Read(buf, 0, sz);
ms.Write(buf, 0, rd);
size -= rd;
}
//img = ImageFromStream(ms);
} else nějak ošéfovat

Nahlásit jako SPAM
IP: 213.211.51.–
NemeK0
Duch
22. 2. 2011   #5
-
0
-

Díky moc, funguje to perfektně!!!!!!!!!!
Ale stejně pořád nechápu, co jsem měl špatně :\ takhle se to nikdy nenaučím.

Nahlásit jako SPAM
IP: 77.48.59.–
NemeK0
Duch
22. 2. 2011   #6
-
0
-

Nechci zakládat nové téma, tak to píšu sem. Chtěl bych se ještě na něco zeptat.
Mám v Console Application Timer, který se spustí každých 10 sekund, netvoří se v základním threadu, aplikace běží dál i bez toho, a funguje jenom když zadám:

while (Connected)

{
Application.DoEvents();
}

Když to nezadám, timer nefunguje. Ale když to zadám, šíleně to žere CPU. Tak čím to nahradit??
Timer jsem nakonec odstranil a vyřešil to líp, ale pořád tento kód potřebuji kvůli další věci. Tak co?

Nahlásit jako SPAM
IP: 77.48.59.–
nervak0
Věrný člen
23. 2. 2011   #7
-
0
-

Nejlepší by bylo nepoužívat to vůbec, a když už, tak rozhodně ne takto. K čemu to potřebuješ? Hoď do přílohy kompletní kód.

Nahlásit jako SPAM
IP: 213.211.51.–
NemeK
~ Anonymní uživatel
8 příspěvků
23. 2. 2011   #8
-
0
-
Nahlásit jako SPAM
IP: 212.47.24.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 5 hostů

Podobná vlákna

Posilani souboru — založil Remder

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý