c# - Sending multiple files Client & Server -
i have client , server code files sending. reason need receive @ client , send server...
everything work perfectly, in cases files sent , received perfectly. in cases after sending few files programm crashes. don't understand problem...
errors:
client
// client code using system; using system.io; using system.collections.generic; using system.linq; using system.net; using system.net.sockets; using system.text; class client003 { const string destfilepath = @"..\..\..\"; const int buffersize = 1024; public static void startreceiving() { // data buffer sending data. byte[] buffer; // filestream read data filestream filestream; int filenamelen = 0; string filename = ""; long filelen = 0; int noofpackets = 0; int receivedbytes = 0; int i, j; // connect remote device. try { // establish remote endpoint socket. // example uses port 11000 on local computer. iphostentry iphostinfo = dns.resolve(dns.gethostname()); ipaddress ipaddress = iphostinfo.addresslist[0]; ipendpoint remoteep = new ipendpoint(ipaddress, 11000); // create tcp/ip socket. socket receiver = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); // connect socket remote endpoint. catch errors. try { receiver.connect(remoteep); buffer = new byte[4]; receiver.receive(buffer, 4, 0); int filesnumber = bitconverter.toint32(buffer, 0); (i = 0; < filesnumber; i++) { buffer = new byte[4]; receiver.receive(buffer, 4, 0); filenamelen = bitconverter.toint32(buffer, 0); // -- buffer = new byte[filenamelen]; receiver.receive(buffer, filenamelen, 0); filename = encoding.utf8.getstring(buffer); // -- buffer = new byte[8]; receiver.receive(buffer, 8, 0); filelen = bitconverter.toint64(buffer, 0); // -- noofpackets = convert.toint32(math.ceiling( convert.todouble(filelen) / convert.todouble(buffersize) )); filestream = new filestream(destfilepath + filename, filemode.openorcreate, fileaccess.write); receivedbytes = 0; // -- (j = 0; j < noofpackets; j++) { if (filelen > buffersize) { buffer = new byte[buffersize]; receivedbytes = receiver.receive(buffer, buffersize, 0); filestream.write(buffer, 0, receivedbytes); filelen -= buffersize; } else { buffer = new byte[filelen]; receivedbytes = receiver.receive(buffer, (int)filelen, 0); filestream.write(buffer, 0, receivedbytes); } } filestream.close(); } // release socket. receiver.shutdown(socketshutdown.both); receiver.close(); } catch (argumentnullexception ane) { console.writeline("argumentnullexception : {0}", ane.tostring()); } catch (socketexception se) { console.writeline("socketexception : {0}", se.tostring()); } catch (exception e) { console.writeline("unexpected exception : {0}", e.tostring()); } } catch (exception e) { console.writeline(e.tostring()); } } public static int main(string[] args) { startreceiving(); return 0; } } server
//server code using system; using system.io; using system.net; using system.net.sockets; using system.text; using system.collections.generic; class server003 { public static void startlistening() { // data buffer incoming data. byte[] buffer; byte[] filenamebyte; byte[] filenamelenbyte; byte[] filelenbyte; // filestream write data filestream filestream; int64 filelen = 0; int noofpackets = 0; int readbytes = 0; int i; // establish local endpoint socket. // dns.gethostname returns name of // host running application. iphostentry iphostinfo = dns.resolve(dns.gethostname()); ipaddress ipaddress = iphostinfo.addresslist[0]; ipendpoint localendpoint = new ipendpoint(ipaddress, 11000); // create tcp/ip socket. socket listener = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); // bind socket local endpoint , // listen incoming connections. try { listener.bind(localendpoint); listener.listen(10); // start listening connections. console.writeline("waiting connection..."); // program suspended while waiting incoming connection. socket handler = listener.accept(); int32 filesnumber = binfilesnames.count; byte[] filesnumberbyte = bitconverter.getbytes(filesnumber); handler.send(filesnumberbyte); // -- foreach (string binname in binfilesnames) { filenamebyte = encoding.utf8.getbytes(binname); filenamelenbyte = bitconverter.getbytes(filenamebyte.length); handler.send(filenamelenbyte); handler.send(filenamebyte); // -- filestream = new filestream(sourcefilepath + binname, filemode.open, fileaccess.read); filelen = filestream.length; filelenbyte = bitconverter.getbytes(filelen); handler.send(filelenbyte); // -- noofpackets = convert.toint32(math.ceiling( convert.todouble(filelen) / convert.todouble(buffersize))); (i = 0; < noofpackets; i++) { if (filelen > buffersize) { buffer = new byte[buffersize]; // reeding data file , writing bytes "buffer" readbytes = filestream.read(buffer, 0, buffersize); // send bytes "buffer" handler.send(buffer, readbytes, socketflags.none); filelen -= buffersize; } else { buffer = new byte[filelen]; // reeding data file , writing bytes "buffer" readbytes = filestream.read(buffer, 0, (int)filelen); // send bytes "buffer" handler.send(buffer, readbytes, socketflags.none); } } filestream.close(); } // release socket. handler.shutdown(socketshutdown.both); handler.close(); } catch (exception e) { console.writeline(e.tostring()); } console.writeline("\npress enter continue..."); console.read(); } public static list<string> getfiles() { var dir = new directoryinfo(sourcefilepath); // folder files var files = new list<string>(); // list file names foreach (fileinfo file in dir.getfiles("t*260000.bin")) { files.add(path.getfilename(file.fullname)); } return files; } public static int main(string[] args) { binfilesnames = getfiles(); startlistening(); return 0; } const string sourcefilepath = @"..\..\..\binaries\"; static list<string> binfilesnames; const int buffersize = 1024; } upd: took account moments pointed lb2. here receive part , works need:
while ((receivedbytes = receiver.receive(buffer)) > 0) // receive bytes "buffer" { var tmpbuff = buffer.take(receivedbytes); // takes first receivedbytes elements bufferlist.addrange(tmpbuff); } but don't understand how sending work. when send whole data @ once - ok, when trying send partially crashes:
this works , whole data sent:
handler.send(buffer); this 1 crashes:
int sentbytes = 0; int sumsentbytes = 0; { // send bytes "buffer" sentbytes = handler.send(buffer, sumsentbytes, buffersize, socketflags.none); sumsentbytes += sentbytes; } while (sentbytes > 0); so best way construct sending of large amounts of data (in case 20mb, depends)?
there multiple bugs in code able pinpoint particular came from. here few things should aware , code needs clean up:
socketclassidisposable, should wrapped inusing. (i don't know if full program, or snippet driver main(), if callstartreceivingenough times, it'll leak memory).filestream(that have inforloop)idisposable, should wrapped inusing. (call.close()may clean enough, still better useusing.)use of
socket.receive()incorrect. cannot assume receive many bytes requested.receive()returns either0if connection lost, or number of bytes (upto requested count) available in receive buffer. go through:buffer = new byte[filenamelen]; receiver.receive(buffer, filenamelen, 0); filename = encoding.utf8.getstring(buffer); // -- buffer = new byte[8]; receiver.receive(buffer, 8, 0); filelen = bitconverter.toint64(buffer, 0);
... quite possible read part of filename bytes, partial filename, , remainder bytes filename (incorrectly) interpreted filelen.
you correctly use
receivedbytescopy received bytes file stream, incorrectly decrementfilelenbuffersizeratherreceivedbytes, corrupting file possibly writing part of stream, in part of code:receivedbytes = receiver.receive(buffer, buffersize, 0); filestream.write(buffer, 0, receivedbytes); filelen -= buffersize;you keep reallocating new
byte[]in loop each call.receiveunnecessary. can keep reusing same buffer.- for server code, exception screenshot posted has
?message (likly encoding issues). please trap , post actual message.
these few things spotted casual review. whether of these culprits, or there other issue hard ascertain these issues present.
Comments
Post a Comment