I am learning sockets and now I want to write file transfer program. I have server part and client part. Server part contains 2 ports: 5000 (commands) and 5001 (files). Now I want to send a file via socket and when I did something is wrong because only 425B of data is sending.
Here is client send method:
private void sendFile(Socket socket) {
File file2 = new File("C:\\Users\\barte\\Desktop\\dos.png");
byte[] bytes = new byte[16 * 1024];
System.out.println(file2.exists());
try (InputStream inputStream = new FileInputStream(file2);
OutputStream outputStream = socket.getOutputStream();
OutputStream secondOutput = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\dos.png")) {
int count;
while ((count = inputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, count);
secondOutput.write(bytes, 0, count);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
As you can see (image below) I am writing this file also locally and everything is ok, all of 73KB of data is writed.
Now, on server side I am trying to receive this file:
case SEND: {
new Thread(() -> {
printWriter.println("Server is receiving files right now...");
try (ServerSocket serverSocket = new ServerSocket(5001)) {
while (true) {
new FilesTransfer(serverSocket.accept()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
break;
}
And inside FilesTransfer run method:
@Override
public void run() {
System.out.println("Hello there");
try {
InputStream inputStream = inSocket.getInputStream();
OutputStream outputStream = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\file");
byte[] bytes = new byte[16 * 1024];
int count;
while ((count = inputStream.read()) > 0) {
outputStream.write(bytes, 0, count);
}
outputStream.close();
inputStream.close();
inSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Where is a bug? Why only empty bytes are sending when locally everything it's fine?
The problem is:
while ((count = inputStream.read()) > 0) {
Your code uses InputStream.read()
, which reads individual bytes (or -1
when end-of-stream). Right now, you are reading individual bytes, interpreting that as a length, and then writing that number of 0x00 bytes from bytes
to the file. This stops when you read a 0x00 byte from the stream.
You need to change this to use InputStream.read(byte[])
:
while ((count = inputStream.read(bytes)) != -1) {
That is, you need to pass bytes
in, and check for the result being unequal to -1
, not if it is greater than zero (0
), although read(byte[])
will only return 0
if the passed in byte array has length zero, so that is not a real concern.