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) {
}
}
Related
i am trying to transfer large file over java socket transfer happen sucessfully but the file recieved miss some data or some bytes in my opinion. (completely new to the sockets)
Server Side Code
try {
File img = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/abc.mkv");
byte[] mybytearr = new byte[8192];
FileInputStream fis = new FileInputStream(img);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
long len = fis.read();
DataOutputStream dos = new DataOutputStream(outputStream);
int read;
while ((read = dis.read(mybytearr)) != -1) {
dos.write(mybytearr, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
Client Side Code
try {
if (inputStream.available() != 0) {
int bytesRead;
int bufferSize = 0;
bufferSize = socket.getReceiveBufferSize();
DataInputStream dis = new DataInputStream(inputStream);
String name = dis.readUTF();
File db = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "abc.mkv");
FileOutputStream output = new FileOutputStream(db);
byte[] buffer = new byte[bufferSize];
int read;
while((read = dis.read(buffer)) !=-1) {
output.write(buffer,0,read);
}
}
} catch (IOException e) {
e.printStackTrace();
}
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();
}
I'm trying to send my image from android client to Java server. Size of image that i'm sending is about 99kb, but server always reads a few kb less, sometimes 98, sometimes 96 and so on. I'd like to know why that data is lost and how can I send image in a proper way. Please help :)
Code:
Client(sending image):
public void sendImage(File file){
try {
out = new PrintWriter(socket.getOutputStream(),true);
out.println("Image");
out.println(file.length());
byte[] byteArray = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(byteArray,0,byteArray.length);
OutputStream os = socket.getOutputStream();
FilterOutputStream bos = new FilterOutputStream(os);
bos.write(byteArray,0,byteArray.length);
bos.flush();
os.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Server(receiving image):
if(input.equals("Image")){
input = in.readLine();
int fileSize = Integer.parseInt(input);
System.out.println("FILESIZE:" +fileSize);
byte[] byteArray = new byte[fileSize];
FileOutputStream fileOutputStream =
new FileOutputStream("filename.jpg");
BufferedOutputStream bos =
new BufferedOutputStream(fileOutputStream);
BufferedInputStream bis = new BufferedInputStream(in_);
int bytesRead = bis.read(byteArray, 0, byteArray.length);
int current = bytesRead;
do {
bytesRead = bis.read(byteArray, current,
(byteArray.length - current));
if (bytesRead >= 0) {
current += bytesRead;
System.out.println(current);
}
} while (bytesRead != -1);
bos.write(byteArray, 0, current);
bos.flush();
bos.close();
}
EDIT
Problem solved, working code is as follows:
Client side:
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
out.writeChar('I');
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[1024];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
out.writeLong(ao.size());
out.write(ao.toByteArray());
out.flush();
out.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Server side:
if(input =='I'){
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
long length = dis.readLong();
File to = new File("filename.jpg");
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(to));
byte[] buffer = new byte[1024];
int len, current = 0;
System.out.println(length);
while ( current != length) {
len = dis.read(buffer);
dos.write(buffer, 0, len);
current += len;
System.out.println(current);
}
dis.close();
dos.close();
}
From my personal experience PrintWriter and Buffers dont work well together..
As buffers trying to read data before you tell it to it can "steal" data that it should not do. For example if you use any kind of buffered reader to read the input on the server side that buffer will steal some parts at the "start" of the incomming image becuase it think's it's just another line. You could always try using DataInputStream and DataOutputStream instead..
Client:
public void sendImage(File file) {
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
out.writeChar('I'); // as image,
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[1024];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
out.writeLong(ao.size());
out.write(ao.toByteArray());
out.flush();
out.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Server:
// assuming folder structure exists.
public void readImage(Socket s, File to) throws IOException {
DataInputStream dis = new DataInputStream(s.getInputStream());
char c = dis.readChar();
if (c == 'I') {
long length = dis.readLong();
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(to));
byte[] buffer = new byte[1024];
int len;
while ((len = dis.read(buffer)) != -1) {
dos.write(buffer, 0, len);
}
dis.close();
dos.close();
}
}
As a starting point, in the client side, you will also need a loop for reading the local image, because are you sure that...
bis.read(byteArray,0,byteArray.length);
... is really reading the whole image? So you will also need a loop as in the server side.
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.
My server is sending several files to my client. However at the client side, it only receives the first file because I don't know how to iterate and get the second file.
The Server sends like this:
ListIterator iter = missingfiles.listIterator();
//missingfiles contain all the filenames to be sent
String filename;
while (iter.hasNext()) {
// System.out.println(iter.next());
filename=(String) iter.next();
File myFile = new File("src/ee4210/files/"+filename);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
//bis.read(mybytearray, 0, mybytearray.length);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = _socket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
}
The client receives like this: (It will only receive the first file and I don't know how to make it loop to receive the next file)
int bytesRead;
int current = 0;
int filecount = 0;
InputStream in;
try {
in = _socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
OutputStream output = new FileOutputStream(
"src/ee4210/files/"+ 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;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
How to receive multiple files from outputstream?
The obvious answer is 'one at a time, with extra information to tell you where one stops and another starts'. The most usual technique is to send the file size ahead of the file, e.g. as a long via DataOutputStream.writeLong(), and at the receiver change your read loop to stop after exactly that many bytes, close the output file, and continue the outer loop that reads the next long or end-of-stream.
You can try this.
I've used a lazy method to check that the end of all 3 files have been received.
int bytesRead;
int current = 0;
int filecount = 0;
InputStream in;
try
{
in = _socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
while(true)
{
String fileName = clientData.readUTF();
// will throw an EOFException when the end of file is reached. Exit loop then.
OutputStream output = new FileOutputStream("src/ee4210/files/"+ 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.close();
}
}
catch (EOFException e)
{
// means we have read all the files
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}