c# 4.0 - Half file transferring in c# via socket? -
i developing file transfer application via middle level greedy routing in file sends greedy , greedy sends file again router problem time client receives complete file , time receive part of file
here code goes server side
ipaddress[] ipaddress = dns.gethostaddresses("127.0.0.1"); ipendpoint ipend = new ipendpoint(ipaddress[0], 5655); socket clientsock = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip); string filepath = ""; filedes = filedes.replace("\\", "/"); while (filedes.indexof("/") > -1) { filepath += filedes.substring(0, filedes.indexof("/") + 1); filedes = filedes.substring(filedes.indexof("/") + 1); } byte[] filenamebyte = encoding.ascii.getbytes(filedes); lblerror.text = ""; lblerror.text = "buffering ..."; byte[] filedata = file.readallbytes(filepath + filedes); byte[] clientdata = new byte[4 + filenamebyte.length + filedata.length]; byte[] filenamelen = bitconverter.getbytes(filenamebyte.length); filenamelen.copyto(clientdata, 0); filenamebyte.copyto(clientdata, 4); filedata.copyto(clientdata, 4 + filenamebyte.length); lblerror.text = ""; lblerror.text = "connection server ..."; clientsock.connect(ipend); lblerror.text = ""; lblerror.text = "file sending..."; // system.threading.thread.sleep(1000); clientsock.send(clientdata); label3.text = clientdata.length.tostring(); lblerror.text = ""; lblerror.text = "disconnecting..."; clientsock.close(); lblerror.text = ""; lblerror.text = "file transferred.";
in client
class destcode { ipendpoint ipend; socket sock; public destcode() { ipend = new ipendpoint(ipaddress.any, 5656); sock = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip); sock.bind(ipend); } public static string receivedpath; public static string curmsg = "stopped"; public static int res; public void startserver() { try { curmsg = "starting..."; sock.listen(100); curmsg = "running , waiting receive file."; socket clientsock = sock.accept(); byte[] clientdata = new byte[1024 * 5000]; int receivedbyteslen = clientsock.receive(clientdata); curmsg = "receiving data..."; int filenamelen = bitconverter.toint32(clientdata, 0); string filename = encoding.ascii.getstring(clientdata, 4, filenamelen); binarywriter bwrite = new binarywriter(file.open(receivedpath +"/"+ filename, filemode.append)); ; bwrite.write(clientdata,4 + filenamelen, receivedbyteslen - 4 - filenamelen); res = receivedbyteslen; if (receivedpath == "") { messagebox.show("no path selected save file"); } curmsg = "saving file..."; bwrite.close(); clientsock.close(); curmsg = "file received ..."; startserver(); } catch (exception ex) { curmsg = "file receving error."; } } }
in greedy
class receivercode { ipendpoint ipend; socket sock; public receivercode() { ipend = new ipendpoint(ipaddress.any, 5655); sock = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.ip); sock.bind(ipend); } public static string receivedpath; public static string curmsg = "stopped"; public static string rout = ""; public static int rlength = 0; public static string msgstatus = ""; public static byte[] send; public void startserver() { try { curmsg = "starting..."; sock.listen(100); curmsg = "running , waiting receive file."; socket clientsock = sock.accept(); byte[] clientdata = new byte[1024 * 5000]; int receivedbyteslen = clientsock.receive(clientdata); system.threading.thread.sleep(5000); rlength = receivedbyteslen; curmsg = "receiving data..."; int receive = clientsock.receive(clientdata); send = new byte[receivedbyteslen]; array.copy(clientdata, send, receivedbyteslen); rout = "start"; clientsock.close(); curmsg = "reeived & saved file; server stopped."; startserver(); } catch (exception ex) { curmsg = "file receving error."; } } }
please me
the problem socket.receive
not guarantee you'll receive bytes asked for. write:
int receivedbyteslen = clientsock.receive(clientdata);
the documentation says:
if using connection-oriented socket, receive method read data available, size of buffer.
the call receive
getting of bytes available. sender hasn't yet sent of bytes, or network stack hasn't received them , made them available.
to reliably send , receive data, receiver has know 1 of 2 things: either how many bytes it's expecting, or there sentinel value says, "that's all, folks." can't count on single receive
call everything.
when transferring files, sender typically includes size of file first 4 bytes of data being sent. code reads first 4 bytes (making sure 4 bytes) determine size, , spins loop, reading data socket until of expected bytes received.
something like:
const int maximumsize = 1000000; // read first 4 bytes var sizebytes = readbytesfromsocket(socket, 4); int size = bitconverter.toint32(sizebytes); var databuffer = readbytesfromsocket(socket, size); // have data byte[] readbytesfromsocket(socket socket, int size) { var buff = new byte[size]; int totalbytesread = 0; while (totalbytesread < size) { int bytesread = socket.receive(buff, totalbytesread, size-totalbytesread, socketflags.none); if (bytesread == 0) { // nothing received. socket has been closed. // maybe error. break; } totalbytesread += bytesread } return buff; }
see blog post on reading streams (and linked parts 1 , 2) more information. blog posts talk streams, concepts same sockets.
Comments
Post a Comment