ftp - Identify an incoming file through NetworkStream C# -


i making client/server chat application using tcpclient , tcplistener classes. should able transfer text messages , files between client , server. able handle text messages making thread each separate client , making secondary thread receiving incoming message making primary thread reserved sending messages. if able identify incoming message file , not text message know how handle using networkstream , filestream. unable so. code handle incoming file here. please tell me if there limitations using networkstream ftp.

answer: build own protocol.

by building own communication protocol can control data/message flow.

for example;
1-user wants send file server
2-client sends command inform server send file.like ;
@file@filename;filesize;
3-server sends ready message client @fileaccepted@ 4-server begins listen buffer packages , when receives writes them stream.
5-when client receives {@fileaccepted@} command begins send packages server. sure buffer sizes same.
6-when bytes complete client sends @fileend@ in diffrent buffer (i use 256 commands , 1024 file transfer)
7-when server receives 256 byte command looks if @fileend@ command , true flushes file stream , closes connection.

i recomment use async

listen connections on server

server.beginaccepttcpclient(serveracceptend,server); 

and when connection present

public void serveracceptend(iasyncresult ar) {     if(!ar.iscompleted)     {         //something went wrong         acceptserver();         return;     }     try     {         var cli = servertc.endaccepttcpclient(ar);         if(cli.connected)         {             //get first command                cli.getstream().beginread(serverredbuffer,0,serverredbuffer.length,serverfirstreadend,cli);         }         else         {             //connection not successfull log , wait             acceptserver();         }     }     catch(exceiption ex)     {         //an error occur log , wait new connections         acceptserver();     }  } 

when first command received ;

    public void serverfirstreadend(iasyncresult ar)     {     if(!ar.iscompleted)     {         //something went wrong         acceptserver();         return;     }         try         {             tcpclient cli = (tcpclient)ar.asyncstate;             int read = cli.getstream().endread(ar);             string req = tostring(serverredbuffer);               if(req.startswith("@file@"))             {                 //file received                 string filename = req.replace("@file@","");                 string[] spp = filename.split(';');                 filename = spp[0];                 serverreceivetotalbytes = convert.toint64(spp[1]);                 cli.getstream().write(tobyte("@fileaccepted@",256),0,256);                 cli.getstream().beginread(serverreceivebuffer,0,1024,serverreadfilecyle,cli)                }             else             {                 //message received             }         }         catch(exception ex)         {             //an error occur log , wait new connections             acceptserver();         }     } 

file receive method ;

    public void serverreadfilecyle(iasyncresult ar)     {         tcpclient cli = (tcpclient)ar.asyncstate;         if(ar.iscompleted)         {             int read = cli.getstream().endread(ar);             if(read == 256)             {                 try                 {                     string res = tostring(serverreceivebuffer);                     if(res == "@fileend@")                         read = 0;                 }                 catch                 {                 }             }             if(read > 0)             {                 serverfile.write(serverreceivebuffer,0,read);                 cli.getstream().beginread(serverreceivebuffer,0,1024,serverreadfilecyle,cli);             }             else             {                 serverfile.flush();                 serverfile.dispose();                 acceptserver();             }         }     } 

this part server side.and client side;

when sending file first send information server file , wait response server.

try {     system.windows.forms.openfiledialog ofd = new system.windows.forms.openfiledialog();     ofd.multiselect = false;     ofd.filename="";     if(ofd.showdialog() == system.windows.forms.dialogresult.ok)     {         filesendpath = ofd.filename;         senderfilestream = system.io.file.open(filesendpath,system.io.filemode.open);         sendertotalbytes = senderfilestream.length;         filesendcommand = "@file@" + system.io.path.getfilename(filesendpath) + ";" + senderfilestream.length;         senderfilestream.position = 0;         sendertc.beginconnect(ip.address,55502,fileconnect,null);     }     else     {         //no file selected     }  } catch(exception ex) {     //error connecting log error } 

if connection successfull , send file command , wait response ;

    public void fileconnect(iasyncresult ar)     {         if(ar.iscompleted)         {             sender.endconnect(ar);             if(sender.connected)             {                 sender.getstream().write(tobyte(filesendcommand,256),0,256);                 sender.getstream().beginread(computernamebuffer,0,256,filesendcylestarter,null);              }         }     } 

when response received if successfull accepted;

    public void filesendcylestarter(iasyncresult ar)     {         if(ar.iscompleted)         {             if(sender.connected)             {                 string kabul = tostring(computernamebuffer);                 if(kabul == "@fileaccepted@")                 {                     senderfilestream.beginread(filesendbuffer,0,1024,filesendcyle,null);                 }             }         }     } 

sending file has 3 steps;
1-read chunk start
2-then send chunk server.if completed send @fileend@ command , skip step 3 3-read next chunk of file
4-return step 2 if file isnt completed

step 1 :

senderfilestream.beginread(filesendbuffer,0,1024,filesendcyle,null); 

step 2-4 :

    public void filesendcyle(iasyncresult ar)     {         if(ar.iscompleted)         {             if(sendertc.connected)             {                 int  read = senderfilestream.endread(ar);                 if(read > 0)                 {                     sendertc.getstream().beginwrite(filesendbuffer,0,read,filesendcyle2,null);                  }                 else                 {                      sendertc.getstream().write(tobyte("@fileend@",256),0,256);                  }             }         }     } 

step 3 :

    public void filesendcyle2(iasyncresult ar)     {         if(ar.iscompleted)         {             if(sendertc.connected)             {                sendertc.getstream().endwrite(ar);                senderfilestream.beginread(filesendbuffer,0,1024,filesendcyle,null);             }         }     } 

in abowe example there 2 methods called tostring() , tobyte().i used them converting strings bytes , bytes strings.here them ;

    public string tostring(byte[] buffer)     {         return encoding.utf8.getstring(buffer).replace("\0","");     }     public byte[] tobyte(string str,int bufferlenght)     {         byte[] buffer = new byte[256];         encoding.utf8.getbytes(str,0,str.length,buffer,0);         return buffer;     } 

the code abowe example isn't perfect , need lots of error handling , flow controls.i write theese give idea , jump start.

hope part of helps ^_^


Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -