Java Socket Programming Buffer for Large File - java

I am trying to transfer a large file from a server to a client. My code so far works but only if I set the buffer size in the client code to the exact size of the file. I won't always know what the file size is going to be. I keep finding examples that claim it doesn't matter what the size of the file or buffer is because it will just keep reading from the input stream...? However, when I implement the code that supposedly does this, it transfers 0 bytes.
Client:
public static void main (String [] args ) throws IOException {
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(hostname, 20000);
System.out.println("Connecting...");
// receive file
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVE);
bos = new BufferedOutputStream(fos);
//////////// replaced this ////////////////////////////
byte[] buffer = new byte[BUFFER_SIZE];
bytesRead = is.read(buffer,0,buffer.length);
current = bytesRead;
do {
bytesRead = is.read(buffer, current, (buffer.length-current));
if(bytesRead >= 0){ current += bytesRead;}
} while(bytesRead > 0);
bos.write(buffer, 0 , current);
///////////////////////////////////////
// with this:
// int count;
// byte[] buffer = new byte[8192];
// while ((count = is.read(buffer)) > 0)
// {
// bos.write(buffer, 0, count);
// }
//////////// transfers 0 bytes ///////////
bos.flush();
System.out.println("File " + FILE_TO_RECEIVE
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null){ fos.close();}
if (bos != null){ bos.close();}
if (sock != null){ sock.close();}
}
}
Server:
public static void main(String[] args) throws IOException{
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(20000);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
}
finally {
if (bis != null){ bis.close();}
if (os != null){ os.close();}
if (sock!=null){ sock.close();}
}
}
}
finally {
if (servsock != null){
servsock.close();
}
}
}
Thank you for your help

Your copy loops are both different, and both nonsense. One of them isn't even a loop. Try this:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
This works for any buffer of size >= one byte.
Use this at both ends.

Related

java: send large files through sockets

So im making a client-server based architecture programm where server is sending a file and client receives it.
I have seen a lot of code parts and i also made a lot where i send small files. ex images. In my case i want to send .wav audio files which are large(40mb). This is what i have done so far. When i run my client, it just proceed to download, but never really downloads the file. I guess its because its too large.
How to send such large files?
server
public void send_file_to_client(String requested_file) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
File FILE_TO_SEND = new File("C:\\ServerMusicStorage\\" + requested_file + ".wav");
byte[] mybytearray = new byte[(int) FILE_TO_SEND.length()];
try {
fis = new FileInputStream(FILE_TO_SEND);
bis = new BufferedInputStream(fis);
} catch (FileNotFoundException ex) {
Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
}
OutputStream os = null;
bis.read(mybytearray, 0, mybytearray.length);
os = connsock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
toClient.writeUTF(Integer.toString(mybytearray.length));
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Done.");
if (bis != null) {
bis.close();
}
if (os != null) {
os.close();
}
if (connsock != null) {
connsock.close();
}
}
client
public static void receive_file(String requested_file) throws IOException {
File file_to_save = new File("C:\\ClientMusicStorage\\" + requested_file + ".wav");
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
//get file size to create the bytearray
String fileSize=fromServer.readUTF();
int final_file_size = Integer.parseInt(fileSize);
byte[] mybytearray = new byte[final_file_size];
InputStream is = clientSocket.getInputStream();
fos = new FileOutputStream(file_to_save);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead
= is.read(mybytearray, current, (mybytearray.length - current));
if (bytesRead >= 0) {
current += bytesRead;
}
} while (bytesRead > -1);
bos.write(mybytearray, 0, current);
bos.flush();
}

InputStream interference in a Two-way file transfer through sockets

After editing my code with y'all suggestions, as well as condensing the code to where i can pinpoint the line of code that is causing the problem.
Server code:`
public class Server2 {
public static void main(String args[]) throws Exception {
ServerSocket servsock = null;
Socket sock = null;
int SOCKET_PORT = 12362;
InputStream is = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
String FILE_TO_SEND = "SFileToBeSent.txt";
String FILE_TO_RECEIVED = "CFileReceived.txt";
int FILE_SIZE = 6022386;
try {
System.out.println("Server created.");
servsock = new ServerSocket(SOCKET_PORT); // creates servsock with socket port
while (true) {
System.out.println("Waiting for connection...");
try {
sock = servsock.accept(); // accepts a socket connection
System.out.println("Accepted connection : " + sock);
System.out.println();
os = sock.getOutputStream(); // sets Output Stream using the sockets output stream
is = sock.getInputStream(); // get input stream from socket
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// send file
File myFile = new File(FILE_TO_SEND); // creates a file using file to send path
byte[] bytearraySent = new byte[(int) myFile.length()]; // creates a byte array the size of myFile
try {
// reads the contents of FILE_TO_SEND into a BufferedInputStream
fis = new FileInputStream(myFile); // creates new FIS from myFile
bis = new BufferedInputStream(fis); // creates BIS with the FIS
bis.read(bytearraySent, 0, bytearraySent.length); // copies the BIS byte array into the byte array
// prints to console filename and size
System.out.println("Sending " + FILE_TO_SEND + "(" + bytearraySent.length + " bytes)");
System.out.println("byte array from file to send:" + bytearraySent);
// copies the byte array into the output stream therefore sending it through the
// socket
os.write(bytearraySent, 0, bytearraySent.length);
os.flush(); // flush/clears the output stream
} finally {
fis.close();
bis.close();
}
System.out.println();
System.out.println("sendFile complete");
System.out.println();
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// receive file
int bytesRead;
byte[] bytearrayReceived = new byte[FILE_SIZE]; // creates byte aray using file size
fos = new FileOutputStream(FILE_TO_RECEIVED); // creates file from path
bos = new BufferedOutputStream(fos); // creates BOS from FOS
int current = 0; // equals the two integers for comparisons later
try {
System.out.println(String.format("Bytes available from received file: %d", is.available()));
System.out.println("byte array from file to receive: " + bytearrayReceived); // debug purposes
while ((bytesRead = is.read(bytearrayReceived)) != -1) {
System.out.println("amount of bytes that was read for while: " + bytesRead);
bos.write(bytearrayReceived, 0, bytesRead);
System.out.println("bos.write");
current += bytesRead;
System.out.println("current += bytesRead;");
}
System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)");
} finally {
fos.close();
bos.close();
}
System.out.println();
System.out.println("receiveFile complete");
System.out.println();
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
} // end of try
finally {
// if any streams or sockets are not null, the close them
if (os != null)
os.close();
if (is != null)
is.close();
if (sock != null)
sock.close();
} // end of finally
} // end of while
} // end of try
finally {
if (servsock != null)
servsock.close();
} // end of finally
}
}
public class Client2 {
public static void main(String args[]) throws Exception {
Socket sock = null; // used in main
String SERVER = "localhost"; // local host
int SOCKET_PORT = 12362; // you may change this
InputStream is = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
String FILE_TO_RECEIVED = "SFileReceived.txt";
String FILE_TO_SEND = "CFileToBeSent.txt";
int FILE_SIZE = 6022386;
try {
sock = new Socket(SERVER, SOCKET_PORT);
System.out.println("Connecting...");
System.out.println();
// get input and output from socket
is = sock.getInputStream(); // get input stream from socket
os = sock.getOutputStream(); // get output stream from socket
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// receive file
int bytesRead;
byte[] bytearrayReceived = new byte[FILE_SIZE]; // creates byte aray using file size
fos = new FileOutputStream(FILE_TO_RECEIVED); // creates file from path
bos = new BufferedOutputStream(fos); // creates BOS from FOS
int current = 0; // equals the two integers for comparisons later
try {
System.out.println(String.format("Bytes available from received file: %d", is.available()));
System.out.println("byte array from file to receive: " + bytearrayReceived); // debug purposes
while ((bytesRead = is.read(bytearrayReceived)) != -1) {
System.out.println("amount of bytes that was read for while: " + bytesRead);
bos.write(bytearrayReceived, 0, bytesRead);
System.out.println("bos.write");
current += bytesRead;
System.out.println("current += bytesRead;");
}
System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)");
} finally {
fos.close();
bos.close();
}
System.out.println();
System.out.println("receiveFile() complete");
System.out.println();
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// send file
File myFile = new File(FILE_TO_SEND); // creates a file using file to send path
byte[] bytearraySent = new byte[(int) myFile.length()]; // creates a byte array the size of myFile
try {
// reads the contents of FILE_TO_SEND into a BufferedInputStream
fis = new FileInputStream(myFile); // creates new FIS from myFile
bis = new BufferedInputStream(fis); // creates BIS with the FIS
bis.read(bytearraySent, 0, bytearraySent.length); // copies the BIS byte array into the byte array
// prints to console filename and size
System.out.println("Sending " + FILE_TO_SEND + "(" + bytearraySent.length + " bytes)");
System.out.println("byte array from file to send:" + bytearraySent);
// copies the byte array into the output stream therefore sending it through the
// socket
os.write(bytearraySent, 0, bytearraySent.length);
os.flush(); // flush/clears the output stream
} finally {
fis.close();
bis.close();
}
System.out.println();
System.out.println("sendFile() complete");
System.out.println();
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
} // end of try
finally {
if (sock != null)
sock.close();
if (os != null)
os.close();
if (is != null)
is.close();
} // end of finally
}
}
Server output:--------------------
Server created.
Waiting for connection...
Accepted connection : Socket[addr=/127.0.0.1,port=51565,localport=12362]
Sending SFileToBeSent.txt(32 bytes)
byte array from file to send:[B#4e25154f
sendFile complete
Bytes available from received file: 0
byte array from file to receive: [B#70dea4e
Client output--------------------
Connecting...
Bytes available from received file: 32
byte array from file to receive: [B#4e25154f
amount of bytes that was read for while: 32
bos.write
current += bytesRead
I still have the issue with InputStream, and i have found out through debugging that both the server and client get stuck on the while() statement that is in the receive section. For the server, it stops immediately, whereas the client goes through the while loop once then stops when it hits the while statement.
If anyone has any suggestions or solutions, then it would be much appreciated!
First , your receiveFile method should read input and write output in a loop.
Second, please close files after done or you may have a resource leak.
public static void receiveFile() throws IOException {
byte[] mybytearray = new byte[FILE_SIZE]; // creates byte aray using file size
fos = new FileOutputStream(FILE_TO_RECEIVED); // creates file from path
bos = new BufferedOutputStream(fos); // creates BOS from FOS
int current = 0; // equals the two integers for comparisons later
try {
while ((bytesRead = is.read(mybytearray)) != -1) {
bos.write(mybytearray, 0, bytesRead );
current += bytesRead;
}
bos.flush(); // clears the buffer
System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)");
} finally {
bos.close();
}
}

Address already in use (bind failed)

I'm using these two java sources to exchange a file between 2 PC(linux and mac).
The problem is showed only on Linux.
I'm using these 2 codes in a thread where i recall more times.
But i have this error: Address already in use (bind failed).
I have searched on the web and on this forum that the problem is the TCP connection still active, so there is a function of the class Server Socket called setReuseAddress(true) which allows me to reuse the address. I call this function after the instantiation of ServerSocket but the problems persists.
How can i resolve this problem?
[EDIT]
Server
{
final int SOCKET_PORT = 13267;
final String FILE_TO_SEND = "/Users/jo/Desktop/cryptedSymmetric.key";
boolean flag = true;
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(); // create unbound ServerSocket
servsock.setReuseAddress(true);
servsock.bind(new InetSocketAddress(SOCKET_PORT));
// while (flag) {
System.out.println("SO_REUSEADDRESS is enabled: " + servsock.getReuseAddress());
System.out.println("Waiting client B...");
try {
sock = servsock.accept();
System.out.println("Connection : " + sock);
// send file
File myFile = new File(FILE_TO_SEND);
byte[] mybytearray = new byte[(int) myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
os = sock.getOutputStream();
System.out.println("Invio del file " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Done.");
flag = false;
} finally {
if (bis != null)
bis.close();
if (os != null)
os.close();
if (sock != null)
sock.close();
}
// }
} finally {
if (servsock != null)
servsock.close();
return flag;
}
}
EDIT Client
{
int SOCKET_PORT = 0;
SOCKET_PORT = 13267;
// final String SERVER = "192.168.1.2";
final String FILE_TO_RECEIVED = "/Users/jo/Desktop/publicB.key";
final int FILE_SIZE = 6022386;
boolean flag = true;
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(address.getHostAddress(), SOCKET_PORT);
System.out.println("Connessione...");
// receive file
byte[] mybytearray = new byte[FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
// bytesRead = is.read(mybytearray, 0, mybytearray.length);
// current = bytesRead;
int count;
while ((count = is.read(mybytearray)) > 0) {
bos.write(mybytearray, 0, count);
}
bos.flush();
System.out.println("File " + FILE_TO_RECEIVED + " scaricato (" + current + " bytes letti)");
flag = false;
} finally {
if (fos != null)
fos.close();
if (bos != null)
bos.close();
if (sock != null)
sock.close();
return flag;
}
}
I call this function after the instantiation of ServerSocket but the problems persists.
That's because you called it too late. You should have observed that the exception was thrown before the call. You need to separate creation from binding:
servsock = new ServerSocket(); // create unbound ServerSocket
servsock.setReuseAddress(true);
servsock.bind(new InetSocketAddress(SOCKET_PORT));
NB your copy code should be the same at both ends, and not like either version you've used, which exhibit various problems and fallacies:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}

Having trouble sending file from server to another Client (Java)

I'm having some difficulties trying to send file from server to the other client.
Let's say I have two clients connected to the server.
Now Server successfully sent the file to the 1st client But then when the server tries to send to the second client the client does not receive it.
Here's some code to begin with :
Server:
public synchronized void sendToAllClients() {
for (Socket z : clientSockets) {
if (z != null) {
System.out.println("TEST");
PrintWriter print = null;
try {
File myFile = new File(FILE PATH);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = z.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Client:
public static void receiveFile(String fileName) {
try {
int bytesRead;
InputStream in = sock.getInputStream();
clientData = new DataInputStream(in);
OutputStream output = new FileOutputStream(
(FILEPATH + FILENAME);
long size = clientData.readLong();
byte[] buffer = new byte[1024];
while (size > 0
&& (bytesRead = clientData.read(buffer, 0,
(int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.flush();
} catch (IOException ex) {
}
}

problem with server and client , working on my machine not working on another

hello guys i have designed a server client which transfers data through sockets. Everything is ok when i run it on my machine it works 100% of the time. When i run the server on another machine and the client on mine, i am unable to get data. when i run the server on my machine and the client on theirs i am unable to put data , but i can get. i dont know what is going on, maybe you can shed some light.
There is more code that makes this work correctly but i omit that out to reduce the complications . Please if you get a chanse look at this and tell me why it works on my system but not on the server? and does anyone know how to debug this? i mean this is run on the server how can i debug a server since i cannot be there (and everything works correctly on my system?)
Server :
if (get.equals("get")) {
try {
Copy copy = new Copy(socket, dir);//maybe dir is not needed
String name = input.substring(4);
File checkFile = new File(dir.getCurrentPath(), name);
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
if (checkFile.isFile() && checkFile.exists()) {
outToClient.writeBytes("continue" + "\n");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
boolean cont = false;
String x;
while (!cont) {
if ((x = inFromServer.readLine()).equals("continue")) {
cont = true;
}
}
copy.copyFile(name);
output = "File copied to client successfully" + "\n";
} else {
outToClient.writeBytes("File failed to be copied to client" + "\n");
output = "";
}
} catch (Exception e) {
output = "Failed to Copy File to client" + "\n";
}
} else if (get.equals("put")) {
//so the client sends: the put request
//then sends the length
try {
DataInputStream inFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
outToClient.writeBytes("continue" + "\n");
long lengthLong = (inFromClient.readLong());
int length = (int) lengthLong;
byte[] recieveFile = new byte[length];//FIX THE LENGTH
// InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("Copy " + input.substring(4));
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead;
int current = 0;
bytesRead = inFromClient.read(recieveFile, 0, recieveFile.length);
current = bytesRead;
do {
bytesRead = inFromClient.read(recieveFile, current, (recieveFile.length - current));
if (bytesRead >= 0)
current += bytesRead;
} while (bytesRead > 0); // FIX THE LENGTH
bos.write(recieveFile, 0, current);
bos.flush();
bos.close();
output = "File copied to Server successfully" + " \n";
The copy class:
File checkFile = new File(dir.getCurrentPath(), file);
if (checkFile.isFile() && checkFile.exists()) {
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
// byte[] receivedData = new byte[8192];
File inputFile = new File(dir.getCurrentPath(), file);
byte[] receivedData = new byte[(int) inputFile.length()];
long length = inputFile.length();
outToClient.writeLong(length);
//maybe wait here for get request?
DataInputStream dis = new DataInputStream(new FileInputStream(getCopyPath(file)));
dis.read(receivedData, 0, receivedData.length);
OutputStream os = socket.getOutputStream();
outToClient.write(receivedData, 0, receivedData.length);//outputStreasm replaced by Datatoutputstream
outToClient.flush();
The client class:
else if (sentence.length() > 3 && sentence.substring(0, 3).equals("get")) {
outToServer.writeBytes(sentence + "\n");
String response = inFromServer.readLine();
if (response.equals("File failed to be copied to client")) {
System.out.println(response);
} else {
DataInputStream inFromClient = new DataInputStream(clientSocket.getInputStream());
DataOutputStream outToClient = new DataOutputStream(clientSocket.getOutputStream());
outToClient.writeBytes("continue" + "\n");
long lengthLong = (inFromClient.readLong());
int length = (int) lengthLong;
byte[] recieveFile = new byte[length];
FileOutputStream fos = new FileOutputStream("Copy " + sentence.substring(4));
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead;
int current = 0;
bytesRead = inFromClient.read(recieveFile, 0, recieveFile.length);
current = bytesRead;
do {
bytesRead = inFromClient.read(recieveFile, current, (recieveFile.length - current));
if (bytesRead >= 0)
current += bytesRead;
} while (bytesRead > 0);
bos.write(recieveFile, 0, current);
bos.flush();
bos.close();
}
} else if (sentence.length() > 3 && sentence.substring(0, 3).equals("put")) {
File checkFile = new File(dir.getCurrentPath(), sentence.substring(4));
if (checkFile.isFile() && checkFile.exists()) {
try {
outToServer.writeBytes(sentence + "\n");
boolean cont = false;
String x;
while (!cont) {
if ((x = inFromServer.readLine()).equals("continue")) {
cont = true;
}
}
String name = sentence.substring(4);
copy.copyFile(name);

Categories

Resources