Java sending and receiving file (byte[]) over sockets
The correct way to copy a stream in Java is as follows:
int count;
byte[] buffer = new byte[8192]; // or 4096, or more
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Wish I had a dollar for every time I've posted that in a forum.
Java sending and receiving file over sockets
One problem is you are overwriting the content of your buffer
while reading from InputStream
byteread = is.read(buffer, 0, buffer.length);
current = byteread;
do{
byteread = is.read(buffer, 0, buffer.length - current);
if (byteread >= 0) current += byteread;
} while (byteread > -1);
InputStream#read states second param as offset where it will be stored in byte array and in your case offset is always 0
, so it will overwrite in each iteration.
I would suggest to simplify your logic of reading from InputStream and writing to OutputStream
byte[] buffer = new byte[16384];
while ((byteread = is.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, byteread);
}
out.flush();
Hope this helps.
Sending Multiple Files Over a Java Socket
TCP is a byte stream. It has no concept of messages. As such, you need to frame the file data in such a way that the receiver knows where one file ends and the next begins. In this case, you need to send the file size before sending the file data, so the receiver knows how many bytes to expect per file.
Also, you are not paying attention properly to the number of bytes that read()
tells you were actually read each time you call it. You are giving it a large buffer, but there is no guarantee that the entire buffer will be filled up. Especially at the end of a file.
And don't transfer binary file data using strings!
Try something more like this instead:
Client:
File fs = new File("Test1.txt");
long fileLength = fs.length();
InetAddress host = InetAddress.getLocalHost();
Socket clientSocket = new Socket(host, 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
long startTime, endTime, tGap, totalTime = 0;
byte[] sendData = new byte[1024];
int numBytes, filesSent = 0;
while (filesSent < 100) {
FileInputStream fin = new FileInputStream(fs);
long thisFileLength = fileLength;
System.out.println("Sending file to server...");
startTime = System.currentTimeMillis();
outToServer.writeLong(thisFileLength);
while (thisFileLength > 0) {
if (thisFileLength < sendData.length) {
numBytes = fin.read(sendData, 0, (int) thisFileLength);
} else {
numBytes = fin.read(sendData, 0, sendData.length);
}
System.out.println(numBytes);
if (numBytes < 1) {
break;
}
outToServer.write(sendData, 0, numBytes);
thisFileLength -= numBytes;
}
outToServer.flush();
endTime = System.currentTimeMillis();
tGap = endTime - startTime;
totalTime = totalTime + tGap;
System.out.println("Finished run " + filesSent + " with a time of " + tGap);
filesSent++;
fin.close();
if (thisFileLength > 0) {
break;
}
}
clientSocket.close();
System.out.println("I am done to send " + filesSent + " times file, and the average time is: " + (double) totalTime / filesSent);
Server:
ServerSocket welcomeSocket = new ServerSocket(6789);
System.out.println("I am starting now....");
Socket connectionSocket;
connectionSocket = welcomeSocket.accept();
DataInputStream inFromClient = new DataInputStream(new BufferedInputStream(connectionSocket.getInputStream()));
long startTime, endTime, tGap, totalTime = 0;
byte[] receiveData = new byte[1024];
int numBytes, filesRecieved = 0;
while (filesRecieved < 100) {
string filename = "receivedFile" + filesRecieved + ".txt";
FileOutputStream outPut = new FileOutputStream(filename);
startTime = System.currentTimeMillis();
long fileLength = inFromClient.readLong();
System.out.println("OG Bytes: " + fileLength);
while (fileLength > 0) {
if (fileLength < receiveData.length) {
numBytes = inFromClient.read(receiveData, 0, (int) fileLength);
}
else {
numBytes = inFromClient.read(receiveData, 0, receiveData.length);
}
if (numBytes < 1) {
break;
}
try {
outPut.write(receiveData, 0, numBytes);
System.out.println(numBytes);
}
catch (Exception e) {
break;
}
fileLength -= numBytes;
}
outPut.close();
endTime = System.currentTimeMillis();
tGap = endTime - startTime;
totalTime = totalTime + tGap;
System.out.println("I have received " + filename + " using time = " + tGap);
filesRecieved++;
if (fileLength > 0) {
break;
}
}
connectionSocket.close();
System.out.println("I am done now... and the average time used to receive each copy is: " + totalTime / filesRecieved);
welcomeSocket.close();
Java , Sending Large Files Over Socket is Consuming too much CPU cycles and is slow
You're copying a byte at a time. This is slow. You're also declaring a byte array but not using it. Try this:
int count;
byte[] buffer = new byte[8192]; // or more, double or quadruple it
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
How do you send a text file through sockets?
First you need to serialize the file then send it, you can't just send a file like that, this has been already answered, so I will not repeat the answer, I will just link an answer other user provided.
Java sending and receiving file (byte[]) over sockets
Try looking up videos how to serialize data in java there are different methods, using bytes like the one linked, this is part of the Java streams tutorial and it is very useful to learn how streams actually operate.
Sending and receiving byte[] using socket
Take a look at the tutorial on Reading from and Writing to a Socket.
To write a byte array to a socket you would:
byte[] message = ...;
Socket socket=new Socket(ipAddress, port);
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(message);
Similarly, to read, you would use socket.getInputStream
.
Java socket application sends additional bytes while trying to send file
You aren't sending extra bytes, and you aren't receiving extra bytes, but you are certainly writing extra bytes to the file at the receiving end.
Your sending code is correct, your receiving code is not. Have a look at the difference between the write()
calls. One uses the receive count: one does not. Former is correct. The way to copy a stream in Java is as follows:
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
out.close();
in.close();
at both ends. However in this case as you keeping the socket open for further commands, you need to send the image size ahead of the image, and you need a way of sending and receiving commands that won't interfere with the images, which BufferedReader
cannot accomplish. So you need to use DataOutputStream
and DataInputStream
, like so:
// At the sender
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(command);
// ...
out.writeLong(imageSize);
// then the copy loop, reading from the image file.
// At the receiver
DataInputStream in = new DataInputStream(socket.getInputStream());
String command = in.readUTF();
// ...
// image reading code
long imageSize = in.readLong();
long total = 0;
int count;
byte[] buffer = new byte[8192];
while (total < imageSize && (count = in.read(buffer, 0, (int)Math.MIN(buffer.length, imageSize-total))) > 0)
{
out.write(buffer, 0, count);
total += count;
}
out.close();
Modulo bugs.
Related Topics
How to Sort List of Objects by Some Property
Why Does Changing the Returned Variable in a Finally Block Not Change the Return Value
How to Load Classes at Runtime from a Folder or Jar
How to Get Screen Resolution in Java
Jackson - Deserialize Using Generic Class
When Is the @JSONproperty Property Used and What Is It Used For
How to Compare Two Dates Without the Time Portion
Inject an Ejb into Jax-Rs (Restful Service)
Why Is the Clone() Method Protected in Java.Lang.Object
Strange Floating-Point Behaviour in a Java Program
Individual and Not Continuous Jtable's Cell Selection
Dealing with "Xerces Hell" in Java/Maven
Design Patterns: Factory VS Factory Method VS Abstract Factory
Differencebetween "Class.Forname()" and "Class.Forname().Newinstance()"
Redirect to an External Url from Controller Action in Spring MVC
Java: Check the Date Format of Current String Is According to Required Format or Not