Avatar billede beef12 Nybegynder
26. november 2006 - 17:29 Der er 15 kommentarer og
1 løsning

Client-Server - Send data i "bidder"

Jeg har en tcpClient som sender filer fra en klient til en server. Som det ser ud nu, kan jeg kun sende 2000000 byte store filer, men kunne godt tænke mig at splitte filen op i mindre stykker fx 4000 bytes pr. styk. Hvordan skal jeg gribe det an?

Nedenfor ses hvordan det er kodet nu, hvor sendContent er fastsat til at fylde max 2000000 bytes

TcpClient client = new TcpClient(server, port);
NetworkStream stream = client.GetStream();

byte[] sendContent = null;
sendContent = StreamToByteArr(file);
stream.Write(sendContent, 0, sendContent.Length);
sendContent = new Byte[2000000];
stream.Close();
client.Close();
Avatar billede arne_v Ekspert
26. november 2006 - 17:48 #1
du behøver ikke læse hele filen op i et byte array først - du kan sagtens læse løbende
Avatar billede beef12 Nybegynder
26. november 2006 - 17:50 #2
ok - hvordan skal jeg gribe den an?
Avatar billede arne_v Ekspert
26. november 2006 - 17:51 #3
men husk at en stream netop er en stream

du streamer 12000 bytes ud med 3 Write af 4000 bytes

på nettet bliver det splittet op i f.ex. 12 pakker af 1000 byte payload

modtager læser f.eks. 500 + 1000 + 2000 + 4000 + 3000 + 1500 bytes

der er ikke nogen "delimiters" i en stream - der er bare en strøm af bytes
som kan grupperes tilfældigt
Avatar billede beef12 Nybegynder
26. november 2006 - 17:51 #4
men det kunne egentlig være meget godt at dele det op i brudstykker, således at jeg med en variabel kan lade brugeren bestemme "chunk"-størrelsen.
Avatar billede arne_v Ekspert
26. november 2006 - 17:52 #5
et klassisk eksempel:

        TcpClient cli = new TcpClient("localhost", 1234);
        Stream nstm = cli.GetStream();
        Stream fstm = new FileStream(@"C:\z.1", FileMode.Open, FileAccess.Read);
        byte[] b = new byte[10000];
        int n;
        while((n = fstm.Read(b, 0, b.Length)) > 0)
        {
            nstm.Write(b, 0, n);
        }
        nstm.Close();
        fstm.Close();
        cli.Close();
Avatar billede arne_v Ekspert
26. november 2006 - 17:52 #6
du kan rette 10000 til 4000 eller 4 hvis du vil
Avatar billede arne_v Ekspert
26. november 2006 - 17:54 #7
hvis du vil sikre dig at modtager kigger på de samme chunks some afsender er
du ned til at indkapsle i en lille protokol

2 byte med længde
data
2 byte med længde
data
2 byte med længde
data

så kan modtager læse indtil han har den samme chunk som afsender sendte det i
Avatar billede beef12 Nybegynder
26. november 2006 - 18:03 #8
Kan du så se hvorfor modtager fejler med Nullref exception når jeg anvender din kode-eksempel?

byte[] databuf = new byte[2000000];
                    while ((i = stream.Read(databuf, 0, databuf.Length)) > 0)
                    {
                        //modtag fil
                        recFile.Write(databuf, 0, i);
                        recFile.Close();

                        //Bekræft
                        reponse = fileName;
                        byte[] msg = System.Text.Encoding.ASCII.GetBytes(reponse);
                        stream.Write(msg, 0, msg.Length);
                        Console.WriteLine("Modtaget filen: {0}", reponse);
                    }
Avatar billede beef12 Nybegynder
26. november 2006 - 18:11 #9
hov havde ikke set dit seneste indlæg. det har sikkert noget at gøre med modtager-fejlen.

Har du et lille eksempel lige ved hånden som du kan copy/paste?
Avatar billede beef12 Nybegynder
26. november 2006 - 20:13 #10
smid også et svar.
Avatar billede arne_v Ekspert
26. november 2006 - 21:30 #11
jeg tror at du er ved at være der hvor du skal "opgradere" fra en rå Stream
til BinaryReader og BinaryWriter
Avatar billede arne_v Ekspert
26. november 2006 - 21:30 #12
her kommer et lille eksempel som bruger de 2
Avatar billede arne_v Ekspert
26. november 2006 - 21:30 #13
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;

namespace E
{
    public class Client
    {
        public static void Main(string[] args)
        {
            TcpClient cli = new TcpClient("localhost", 1234);
            Stream stm = cli.GetStream();
            BinaryWriter br = new BinaryWriter(stm);
            br.Write("Nu kommer der 2 pakker af henholdvis 5 og 7 bytes");
            br.Write(5);
            br.Write(new byte[] { 1, 2, 3, 4, 5 });
            br.Write(7);
            br.Write(new byte[] { 6, 7, 8, 9, 10, 11, 12});
            br.Close();
            stm.Close();
            cli.Close();
        }
    }
}
Avatar billede arne_v Ekspert
26. november 2006 - 21:30 #14
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace E
{
    public class Server
    {
        public static void Main(string[] args)
        {
            TcpListener srv = new TcpListener(IPAddress.Any, 1234);
            srv.Start();
            TcpClient cli = srv.AcceptTcpClient();
            Stream nstm = cli.GetStream();
            BinaryReader br = new BinaryReader(nstm);
            string txt = br.ReadString();
            Console.WriteLine(txt);
            int n1 = br.ReadInt32();
            Console.WriteLine(n1 + " bytes");
            for(int i = 0; i < n1; i++)
            {
                byte b = br.ReadByte();
                Console.WriteLine(b);
            }
            int n2 = br.ReadInt32();
            Console.WriteLine(n2 + " bytes");
            for(int i = 0; i < n2; i++)
            {
                byte b = br.ReadByte();
                Console.WriteLine(b);
            }
            br.Close();
            nstm.Close();
            cli.Close();
            srv.Stop();
        }
    }
}
Avatar billede arne_v Ekspert
26. november 2006 - 21:31 #15
eksemplet skulle gerne illustrere hvordan man chunker på modtager side svarende
til afsender siden

ReadByte kan naturligvis erstattes af en Read som læser flere bytes

og et svar
Avatar billede beef12 Nybegynder
26. november 2006 - 22:17 #16
Det spiller bare nu.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester