Java Sending and Receiving File (Byte[]) Over Sockets

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



Leave a reply



Submit