In my project, I am trying to send a file to every connected clients.I used thread to send file to the clients.But when I tried to test this I found that 3 clients of total 7 got the complete pdf file but rest of them got only some bytes. What is the efficient way to implement file transfer in java socket programming so that I can send a file to more than 100 clients at the same time?
File Sending code
while(true){
try {
if(Helper.sendFile)
{
System.out.println("file sending...");
File file = new File(Helper.quesPath);
// Get the size of the file
long length = file.length();
byte[] bytes = new byte[16 * 1024];
InputStream in = new FileInputStream(file);
OutputStream out = socket.getOutputStream();
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
System.out.println("ec : "+count);
}
//out.close();
out.flush();
in.close();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
File receiving code
while (true)
{
if(Helper.sendFile)
{
try {
in = socket.getInputStream();
String x=System.getProperty("user.home");
out = new FileOutputStream(x+"/Desktop/"+Helper.courseCode+".pdf");
System.out.println(x);
byte[] bytes = new byte[16*1024];
int count;
while (true) {
count = in.read(bytes);
System.out.println("v : "+count);
if(count < 16380){
out.write(bytes, 0, count);
break;
}else{
out.write(bytes, 0, count);
}
}
System.out.println("File Done");
//in.close();
out.close();
break;
} catch (Exception ex) {
System.out.println("File not found. ");
}
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
I think the problem you have is in when reading it from the client.
I presume that the magic number 16380 is the expected length of the file. So what you need to do is something a bit different:
int count = 0;
while (count < 16380) {
int incoming = in.read(bytes);
System.out.println("v : " + incoming);
if (incoming > 0) {
out.write(bytes, 0, incoming);
count += incoming;
} else if (incoming < 0) {
//end of stream
break;
}
}
This loop will keep on looping until the number of bytes read (count
) reaches your magic number.
Something I would also do is use more efficient input streams, like a BufferedInputStream
.
So in your first line in the block you do:
in = new BufferedInputStream(socket.getInputStream());
If you want a high number of concurrent connections it might make sense to look at making your server non-blocking with NIO. But the paradigm is a bit different.