Avatar billede beef12 Nybegynder
23. november 2006 - 17:38 Der er 21 kommentarer og
1 løsning

Problemer med upload af fil.

Prøver at sende en fil fra en client til en server:

//client
FileInfo f = new FileInfo(@"c:\data\myfile.txt");
FileStream sendFile = f.Open(FileMode.Open, FileAccess.Read);
// Inialisere
                TcpClient client = new TcpClient(server, port);
                // Send besked
                byte[] content = ReadFile(file);
                NetworkStream stream = client.GetStream();
                stream.Write(content, 0, content.Length);
                Console.WriteLine("Sent: {0}", file);
                content = new Byte[4096];



//server

                while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                {
                    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                    Console.WriteLine("Received: {0}", data);
                    data2 = "Modtaget!";
                    byte[] msg = System.Text.Encoding.ASCII.GetBytes(data2);
                    stream.Write(msg, 0, msg.Length);
                    Console.WriteLine("Sendt: {0}", data2);
                }


Det virker fint, men når jeg sender en gif fil, begynder server-applikationen af forårsage bip-lyde fra mit motherboard... meget mystisk. Nogen der kan se hvad jeg gør galt?
Avatar billede arne_v Ekspert
23. november 2006 - 17:50 #1
GIF er en binær fil - du kan ikke konvertere den til String
Avatar billede beef12 Nybegynder
23. november 2006 - 18:06 #2
nå for pokker - er det bare derfor. Vil det sige at jeg bare kan gemme den som fil på server?
Avatar billede beef12 Nybegynder
23. november 2006 - 18:11 #3
og hvis ja - kan man på en eller anden smart måde dumpe data til en fil, så jeg kan gemme den?

Smid også lige et svar.
Avatar billede beef12 Nybegynder
23. november 2006 - 18:32 #4
glem det sidste spm - bare smid svar. Fik løst det :-)
Avatar billede arne_v Ekspert
23. november 2006 - 18:48 #5
et typisk kode fragment (dog singlethreaded):

        TcpListener srv = new TcpListener(IPAddress.Any, 1234);
        srv.Start();
        TcpClient cli = srv.AcceptTcpClient();
        Stream nstm = cli.GetStream();
        Stream fstm = new FileStream(@"C:\z.2", FileMode.CreateNew, FileAccess.Write);
        byte[] b = new byte[10000];
        int n;
        while((n = nstm.Read(b, 0, b.Length)) > 0)
        {
            fstm.Write(b, 0, n);
        }
        nstm.Close();
        fstm.Close();
        cli.Close();
        srv.Stop();
Avatar billede arne_v Ekspert
23. november 2006 - 18:48 #6
og et svar
Avatar billede beef12 Nybegynder
23. november 2006 - 19:00 #7
Er det egentlig muligt vha den kode viser at sende et filnavn - eller skal den sendes med seperat?
Avatar billede arne_v Ekspert
23. november 2006 - 19:17 #8
du kan lave en lille protokol for hvad der sendes

eksempel:

1 byte med længden på filnavn
X bytes med filnavn
Y bytes med fil indhold
Avatar billede beef12 Nybegynder
23. november 2006 - 19:19 #9
ah - den forstod jeg ikke helt
Avatar billede arne_v Ekspert
23. november 2006 - 19:54 #10
client sender først 1 byte med længden af filnavnet
derefter sender den bytes med filnavnet
og til sidst sender den bytes indholdet af filen

server læser først længden
så filnavnet hvorefter den åbner en stream til filen
filens indhold skrives så til filen
Avatar billede beef12 Nybegynder
23. november 2006 - 20:09 #11
hvad hvis længden er 200 - giver det ikke problemer?
Avatar billede arne_v Ekspert
23. november 2006 - 20:16 #12
C# byte er unsigned d.v.s. 0-255

vil du kunne angive længere filnavne så brug 2 bytes
Avatar billede beef12 Nybegynder
23. november 2006 - 20:37 #13
Ok. har du et kodeeksempel?

Jeg gætter på at man på klient siden skal se således ud:

                byte[] sendLength = StrToByteArray(fileName.Length.ToString());
                byte[] sendFileName = StrToByteArray(fileName);
                byte[] sendContent = ReadFile(file);

                NetworkStream stream = client.GetStream();

                stream.Write(sendLength, 0, sendLength.Length);
                sendLength = new Byte[1];

                stream.Write(sendFileName, 0, sendFileName.Length);
                sendFileName = new Byte[4096];
               
                stream.Write(sendContent, 0, sendContent.Length);
                sendContent = new Byte[4096];

Men hvordan fisker jeg så filnavn/længde ud i min nedenstående while:

                while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                {
                    //modtag fil
                    FileStream recFile = File.OpenWrite(@"C:\DATA\OUTPUT\<<filnavn>>");
                    recFile.Write(bytes, 0, i);
                    recFile.Close();
}
Avatar billede arne_v Ekspert
23. november 2006 - 21:00 #14
jeg prøver at bixe et eksempel
Avatar billede arne_v Ekspert
23. november 2006 - 21:32 #15
client:

            int lenfilename = Encoding.Default.GetByteCount(filename);
            stm.WriteByte((byte)lenfilename);
            stm.Write(Encoding.Default.GetBytes(filename), 0, lenfilename);
            stm.Write(data, 0 , data.Length);
Avatar billede arne_v Ekspert
23. november 2006 - 21:33 #16
server:

            int lenfilename = nstm.ReadByte();
            byte[] filenamebuf = new byte[lenfilename];
            int ix = 0;
            int n;
            while(ix < lenfilename && (n = nstm.Read(filenamebuf, ix, lenfilename - ix)) > 0)
            {
                ix += n;
            }
            string filename = Encoding.Default.GetString(filenamebuf);
            Stream fstm = new FileStream(filename, FileMode.Create, FileAccess.Write);
            byte[] databuf = new byte[10000];
            while((n = nstm.Read(databuf, 0, databuf.Length)) > 0)
            {
                fstm.Write(databuf, 0, n);
            }
            fstm.Close();
Avatar billede beef12 Nybegynder
23. november 2006 - 22:31 #17
Cool... det virker... næsten :-)
Den skriver stadig filnavnet ind i selve filen - kan du se hvad vi gør forskelligt. Eller går den også det i din app?

NetworkStream stream = client.GetStream();

int i;
int lenfilename = stream.ReadByte();
byte[] filenamebuf = new byte[lenfilename];
int ix = 0;

while (ix < lenfilename && (i = stream.Read(filenamebuf, ix, lenfilename - ix)) > 0)
{
  ix += i;
}

string fileName = Encoding.Default.GetString(filenamebuf);
FileStream recFile = File.OpenWrite(@"C:\DATA\OUTPUT\" + fileName);
byte[] databuf = new byte[10000];

while ((i = stream.Read(databuf, 0, databuf.Length)) > 0)
{

  recFile.Write(databuf, 0, i);
  recFile.Close();
}
stream.Close();
client.Close();
Avatar billede arne_v Ekspert
23. november 2006 - 22:41 #18
det gør den ikke
Avatar billede arne_v Ekspert
23. november 2006 - 22:42 #19
hvordan ser din client kode ud ?
Avatar billede beef12 Nybegynder
23. november 2006 - 22:49 #20
Nå ja - det er nok der skoen trykker:

NetworkStream stream = client.GetStream();
stream.WriteByte((byte)lenfilename);
stream.Write(Encoding.Default.GetBytes(fileName), 0, lenfilename);
stream.Write(sendFileName, 0, sendFileName.Length);         
stream.Write(sendContent, 0, sendContent.Length);
sendContent = new Byte[4096];
stream.Close();
client.Close();
Avatar billede beef12 Nybegynder
23. november 2006 - 22:53 #21
ser vist ud til at jeg sender filename 2 gange...
Avatar billede beef12 Nybegynder
23. november 2006 - 23:12 #22
jeps - så fik jeg ram på fejlen. Du skal have stor tak for din hjælp.
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