I have made server client application where server will send a file to client and client will receive it and save it in C:/ on any place.
I first send a string "File" in order to tell client to receive file and than server send file name and size to client and then start sending it.
Problem is that client doesnt receive file although it read in loop and get all bytes but doesnt write to required file object. Please have a look on client code I HAVE SHOWN WHERE IT STUCKS
Following is server code :
public void run(){
try{
System.out.println("Starting writing file");
objOut.writeObject("File");
objOut.flush();
File f= new File(filePath);
String name= f.getName();
int length =(int) f.length();
objOut.writeObject(name);
objOut.flush();
objOut.writeObject(length);
objOut.flush();
byte[] filebytes = new byte[(int)f.length()];
FileInputStream fin= new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(filebytes, 0, filebytes.length);
BufferedOutputStream bout = new BufferedOutputStream(objOut);
bout = new BufferedOutputStream(objOut);
bout.write(filebytes, 0, filebytes.length);
bout.flush();
System.out.println("File completelty sent");
}
catch(Exception ex)
{
System.out.println("error on writing file : "+ex.getMessage());
}
}
Following is client code :
while(true){
fobjIn = new ObjectInputStream(fileSock.getInputStream());
String str = (String) fobjIn.readObject();
if(str.equals("File"))
{
System.out.println("Starting receiving file");
ReceiveFile();
}
System.out.println(str);
}
public void ReceiveFile() throws Exception{
String name =(String)fobjIn.readObject();
File f = new File("C:/Temp/" +name);
f.createNewFile();
int length = (int) fobjIn.readObject();
FileOutputStream fout = new FileOutputStream(f);
BufferedOutputStream buffout = new BufferedOutputStream(fout);
byte[] filebyte = new byte[length];
int bytesRead=0,current=0;
bytesRead = fobjIn.read(filebyte, 0, filebyte.length);
do {
bytesRead = fobjIn.read(filebyte, current, (filebyte.length-current));
if(bytesRead > 0) {
current += bytesRead;
System.out.println("writting" + bytesRead);
}
else break;
} while(bytesRead > -1);
^^^^^^^IT DOESNT COMEOUT FROM LOOP while begugging^^^^^^^^
buffout.write(filebyte, 0 , current);
buffout.flush();
System.out.println("written");
}
You should probably close your stream on the server side when you are done sending, so that the client can be notified that the server is done sending. Or else it'll just sit there waiting for more data.
Related
I am trying to create a simple server-client-program where the user can upload and download files. I have got the Sockets and Streams to work, and I can upload a file to the server. But whenever one file has been uploaded the Server-side seems to get stuck in the loop that reads the streams and forwards it to the Server-file.
Server Code:
InputStream in = clientSocket.getInputStream();
String filePath = "......."
+ op[1];
System.out.println(op[0] + ": " + filePath);
FileOutputStream out = new FileOutputStream(filePath);
byte[] bytes = new byte[16*1024];
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
Client Code:
String filePath = "...."
+ path;
System.out.println("Attempting: " + filePath);
dos = new DataOutputStream(serverSocket.getOutputStream());
fis = new FileInputStream(filePath);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
dos.write(buffer);
}
dos.flush();
fis.close();
The problem is that the program gets stuck at the while-loop, so the Server can not perform anything else. There are no errors or anything...
You never close the stream on the client side. Add dos.close() after dos.flush()!
I am writing a file storage and transfer system using Java. Here's the code on the client side to receive a file:
public static void receiveFile(Socket socket) throws IOException{
String fileLocation="/home/limafoxtrottango/Downloads/receivedFile";
int bytesRead=0;
int current = 0;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
// receive file
byte [] byteArray = new byte [60022386];
System.out.println("Waiting to receive a file...");
//reading file from socket
InputStream inputStream = socket.getInputStream();
fileOutputStream = new FileOutputStream(fileLocation);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bytesRead = inputStream.read(byteArray,0,byteArray.length); //copying file from socket to byteArray
current = bytesRead;
do {
bytesRead =inputStream.read(byteArray, current, (byteArray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bufferedOutputStream.write(byteArray, 0 , current); //writing byteArray to file
bufferedOutputStream.flush(); //flushing buffers
System.out.println("File " + fileLocation + " downloaded ( size: " + current + " bytes read)");
} catch(SocketException e){
System.out.println("Some error occured");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if (fileOutputStream != null) fileOutputStream.close();
if (bufferedOutputStream != null) bufferedOutputStream.close();
if (socket != null) socket.close();
}
}
While receiving a file, I get the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:128)
at Test.receiveFile(Test.java:211)
at Test.main(Test.java:70)
Note: The error is in the following line of the code:
bufferedOutputStream.write(byteArray, 0 , current);
After debugging, I found-out that the client does not have any data in it's input stream, and hence, the read() method always returns -1 (eof). But the server is sending the file successfully.
Here is the code for the server:
public static void sendFile(Socket socket, String fileLocation)
{
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
OutputStream outputStream = null;
File file = new File (fileLocation);
byte [] byteArray = new byte [(int)file.length()];
try {
socket=new Socket(socket.getInetAddress(),port_no);
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(byteArray,0,byteArray.length); // copied file into byteArray
//sending file through socket
outputStream = socket.getOutputStream();
System.out.println("Sending " + fileLocation + "( size: " + byteArray.length + " bytes)");
outputStream.write(byteArray,0,byteArray.length); //copying byteArray to socket
outputStream.flush(); //flushing socket
System.out.println("Done sending!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And here is my call to the above method:
sendFile(clientSocket, "/home/limafoxtrottango/Downloads/serverDownloads/"+sender);
The thing is that the server is successfully writing the byte into the stream, but the client doesn't seem to have any data in it's input stream.
https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)
inputStream.read(byteArray,0,byteArray.length); may return -1 in some cases as given in documentation above. Please cater for such situations.
In addition, I would suggest to use solution given here for both client and server: Efficient way to write InputStream to a File in Java (Version 6)
Client code:
final Path destination = Paths.get(fileLocation);
try (
final InputStream in = socket.getInputStream();
) {
Files.copy(in, destination);
}
Server code:
try (
final InputStream in = new FileInputStream(fileLocation);
) {
Files.copy(in, socket.getOutputStream());
}
Kind regards,
Bala
The server isn't sending anything, contrary to your title. It is closing the connection immediately, so bytesRead is initially -1 and never changes, and you aren't defending against that, so you get the ArrayIndexOutOfBoundsException.
However in the code you posted, the server is sending something but never closing the socket, which is another bug you need to fix. It is also ignoring the count returned by FileInputStream.read() and assuming it filled the buffer, which isn't part of the specification.
So either this is not the real server code or you are connecting to something else, or the server got an IOException that you haven't mentioned.
It's curious that you use two different pieces of code for copying. The standard way to copy a stream in Java is this:
char buffer = new char[8192]; // or whatever size you prefer > 0
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Use this at both ends. There is no need for heroically sized buffers, or buffers the size of the file, or assuming that the file size fits into an int.
I'm trying to figure out how to get a list of files on the server and how to download them individually. Can anyone guide me in the right direction?
I'm getting file permissions error or (is a directory errors), thanks
UPDATE:
The error is
Exception in thread "main" java.io.FileNotFoundException: /myClientFiles (Permission denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at
xxxxxxpackegename.com.fr(Client.java:38)
Client.java
public class Client {
private static final int PORT = 2665;
private static String HOST = "localhost";
public static void main(String[] args) throws UnknownHostException, IOException {
int filesize = 5000000; //buffer size 5mb
int bytesRead;
int currentTotalNumberOfBytes = 0;
//connect to port on server - server waits for this after running socket.accept() in the Server class
Socket socket = new Socket(HOST, PORT);
byte[] byteArray = new byte[filesize]; //create a byte array of 5mb
InputStream inputStream = socket.getInputStream(); //channel to write to server
FileOutputStream fileOutStream = new FileOutputStream("/myClientFiles");
BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
bytesRead = inputStream.read(byteArray, 0, byteArray.length);
currentTotalNumberOfBytes = bytesRead;
do { //read till the end and store total in bytesRead and add it to currentTotalNumberOfBytes
bytesRead = inputStream.read(byteArray, currentTotalNumberOfBytes, (byteArray.length-currentTotalNumberOfBytes));
if(bytesRead >= 0) currentTotalNumberOfBytes += bytesRead;
}while(bytesRead > -1); // when bytesRead == -1, there's no more data left and we exit the loop
bufferOutStream.write(byteArray, 0 , currentTotalNumberOfBytes); //write the bytes to the file
bufferOutStream.flush();
bufferOutStream.close();
socket.close();
}
}
Server.java
ServerSocket serverSocket = new ServerSocket(2665);
Socket socket = serverSocket.accept();
System.out.println("Connected to: " + socket);
//File transferFile = new File("Allcrisis.doc"); //get local file
File[] transferFiles = new File("/myServerFiles").listFiles(); //array to store pathnames of files in myServerFiles folder
byte[] bytearray = new byte[(int)transferFiles.length];
for(File file: transferFiles){
//FileInputStream fileInputStream = new FileInputStream(transferFiles);
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream butterInputStream = new BufferedInputStream(fileInputStream);
butterInputStream.read(bytearray, 0, bytearray.length);
OutputStream outStream = socket.getOutputStream();
System.out.println("Sending...");
outStream.write(bytearray, 0, bytearray.length);
outStream.flush();
}
socket.close();
You have a folder /myClientFiles.
Your code contains
new FileOutputStream("/myClientFiles")
which attempts to open a FileOutputStream to write to that folder. You can't write to a folder.
You might want to pass new FileOutputStream the path to the file to write to.
i am trying to make a java server that will send images stored in a database to android device.
for now am trying with simple image that stored on the hard disk for the server to send.
my question is can i send an image from java server as a byte array to android via TCP sockets.
Yes, you can, using TCP sockets.
Read the file as bytes and send it as bytes, don't try to load it as a BufferedImage.
Then, on the receiving end, use a function that allows you to load an image from an array of bytes.
Sure, you can, but you will need to invent your own protocol for that. You may find using HTTP more, either setting up a web-server like Tomcat with your application deployed there, or use something embedded like Jetty
The fastest and easiest approach for sending image is as follows...
Try this
// Server Side code for image sending
ServerSocket servsock = new ServerSocket(13250);
System.out.println("Main Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
File myFile = new File ("\sdcard\ab.jpg");
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);*/
byte [] mybytearray =new byte[count];
System.arraycopy(Copy, 0, mybytearray, 0, count);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
sock.close();
servsock.close();
//Client side code for image reception
try
{
int filesize=6022386; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
// localhost for testing
ServerSocket servsocket = new ServerSocket(13267);
System.out.println("Thread Waiting...");
Socket socket = servsocket.accept();
System.out.println("Accepted connection : " + socket);
System.out.println("Connecting...");
File f=new File("\sdcard\ab.jpg");
f.createNewFile();
// receive file
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream 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);
count=current;
Copy=mybytearray.clone();
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
fos.close();
socket.close();
servsocket.close();
}
} catch(IOException e)
{
System.out.println("errorr");
}
Hello everyone ,
I am trying to develop the application for transfering/sending the file like SKYPE works.So I am using socket for transfering file from one computer(client) to another computer(client) .I am able to transfer file from one client to server using this. code.But when I try to send the same file from server to second client.It is transfering with 0 byte also give socket close exception so I try to create new socket object at client side.So Now the Exception not coming but file not transfering to client.After debugging I found that the file is successfully sent to client by server but at client side socket is not able to read the data and waiting for data.I can’t find any better solution.If anyone knows anything about this Please tell me.If you have any other solution for file transfer than also tell me.Thanks in advance
Below is my code
Server code:
public class ChatServer
{
serversocket = new ServerSocket(1436);
thread = new Thread(this);
thread.start();
/*************Thread Implementation***************/
public void run()
{
/*********Accepting all the client connections and create a seperate thread******/
while(thread != null)
{
try
{
/********Accepting the Server Connections***********/
socket = serversocket.accept();
/******* Create a Seperate Thread for that each client**************/
chatcommunication = new ChatCommunication(this,socket);
thread.sleep(THREAD_SLEEP_TIME);
}
catch(InterruptedException _INExc) { ExitServer(); }
catch(IOException _IOExc) { ExitServer(); }
}
}
protected void SendGroupFile(Socket ClientSocket, String FileName,String GroupName,String UserName) throws IOException
{
try
{
// receive file from Client
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(Filepath);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =is.read(mybytearray, current, (mybytearray.length-current));
System.out.println("Reading Bytes server"+bytesRead);
if(bytesRead >= 0)
current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray,0,current);
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/***** Function To Send a File to Client **********/
protected void SendGroupFileClient(Socket ClientSocket, String FileName,String GroupName,String UserName)
{
try {
int m_userListSize = userarraylist.size();
clientobject = GetClientObject(GroupName);
if(clientobject != null)
for(G_ILoop = 0; G_ILoop < m_userListSize; G_ILoop++)
{
clientobject = (ClientObject) userarraylist.get(G_ILoop);
if((clientobject.getGroupName().equals(GroupName)) && (!(clientobject.getUserName().equals(UserName))))
{
{
File myFile = new File (Filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = socket.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
}
}catch(IOException _IOExc)
{
_IOExc.printStackTrace();
}
}
}
ChatCommunication .java
public class ChatCommunication implements Runnable,CommonSettings
{
Thread thread;
Socket socket;
DataInputStream inputstream;
String RFC;
ChatServer Parent;
/********Initialize the Socket to the Client***********/
ChatCommunication(ChatServer chatserver,Socket clientsocket)
{
Parent = chatserver;
socket = clientsocket;
try
{
inputstream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}catch(IOException _IOExc) { }
thread = new Thread(this);
thread.start();
}
public void run()
{
while(thread != null)
{
try {
RFC = inputstream.readLine();
if(RFC.startsWith("FILEGRUP"))
{
Parent.SendGroupFile(socket,RFC.substring(9,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));
}
if(RFC.startsWith("FILEGET"))
{
Parent.SendGroupFileClient(socket,RFC.substring(8,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));
}
}catch(Exception _Exc)
{
Parent.RemoveUserWhenException(socket);QuitConnection();
}
}
}
Client code
class Client extends JFrame
{
ServerName="192.168.1.103";
ServerPort=1436;
Client()
{
socket = new Socket(ServerName,ServerPort);
SendGroupFileToServer(Filepath,SelectedGroup);
}
/*******Function To Send File To Server and receiving the file ***********/
protected void SendGroupFileToServer(String FileName, String ToGroup)
{
try {
dataoutputstream.writeBytes(FileName.concat("!").concat(ToUser)+"\r\n");
//send file to sever
File myFile = new File (FileName.substring(9));
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
System.out.println("File successfully Sended to server");
}catch(IOException _IoExc) { QuitConnection(QUIT_TYPE_DEFAULT);}
try {
socket1 = new Socket(ServerName,ServerPort); //Creating new Socket
dataoutputstream = new DataOutputStream(socket1.getOutputStream());
dataoutputstream.writeBytes("FILEGET"+FileName.concat("!").concat(ToGroup+"*"+UserName)+"\r\n"); //sending string to server
} catch (IOException e1) {
e1.printStackTrace();
}
// receive file sended by server
byte [] mybytearray = new byte [filesize];
InputStream is;
try {
is = socket1.getInputStream();
FileOutputStream fos = new FileOutputStream(Filepath);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead; //up to this working fine
do {
bytesRead =is.read(mybytearray, current, (mybytearray.length-current)); //not reading the file data sent by server just waiting and not go ahead
if(bytesRead >= 0)
current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray,0,current);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
There are so many problems here that it is difficult to know where to start.
The thread.sleep() in the accept() loop is literally a waste of time. It serves no useful purpose except possibly to throttle the rate at which clients are accepted. If that wasn't your intention, don't do it.
All you are doing when you catch an exception is exiting the server without even printing the exception message. So when something goes wrong, as it is here, you can't possibly know what it was. Don't do that.
readLine() returns null at EOS, on which you must close the socket, stop reading, and exit the thread. You aren't testing that, and you are therefore omitting all three of those required steps. Don't do that.
You are constructing a DataInputStream around a BufferedInputStream for use when reading commands, but you aren't passing it to the methods that process those commands. You are just passing the socket. You are therefore losing data. Don't do that. Every part of the program must use the same input stream or reader for the socket.
You are reading the entire file into memory. This (a) assumes the file size fits into an int; (b) does not scale to large files; (c) wastes space, and (d) adds latency. Don't do that.
You are ignoring the result of the read() into that buffer and assuming it was filled. You can't do that. The correct way to copy streams in Java is shown below. This works with a buffer of any size, e.g. 8192, for an input of any length, and doesn't require you to buffer the entire input into memory. You can use this loop at both the client when sending the file and at the server when receiving it.
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Similarly to (4) above, you are using a DataOutputStream around a BufferedOutputStream for some things and the socket output stream directly for others. Don't do that. All parts of the program must the same output stream or writer for the socket.
You don't need to flush() before close(); it happens automatically.
For some reason after sending the file you are creating a new connection and sending another command. You aren't even closing the connection afterwards. The server will have no easy way of knowing that this connection and this command referred to the file just sent in the code above. It is also redundant, as the receipt of the final EOS tells the server that the file has been sent successfully. Don't do this. If you need to send more information with the file, send it first, before the file, on the same connection.
The reference you cite exhibits many of the above issues. Make an effort to find a reputable starting point.
This is the solution. Please Apply this logic to your code.
I am able to send a file from server to client and client to server.
Check the following code to send the file from Client to Server. It is working great.
If you have any issues let me know.
Server Side Code:
public class ServerRecieveFile {
public static void main(String[] args) throws IOException {// TODO Auto-enerated method stub int filesize=1022386;
int bytesRead; int currentTot= ;
ServerSocket serverSocket=new ServerSocket(15123);
Socket socket=rverSocket.accept();
byte [] bytearray = new byte [filesize];
InputStream is=socket.getInputStream();
File copyFileName=new File("c:/Files Sockets/2.txt");
FileOutputStream fos = new FileOutputStream(copyFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead;
do {
bytesRead =is.read(bytearray, currentTot, (bytearray.length-currentTot)); if(bytesRead >= 0)
currentTot += bytesRead;
} while(bytesRead > -1);
bos.write(bytearray, 0 , currentTot);
bos.flush();
bos.close();
socket.close();
}
}
Client Side code:
public class ClientSendFile {
public static void main(String[] args) throws UnknownHostException, IOException {// TODO Auto-generated method stub
Client client=new Client();
Socket socket = new Socket(InetAddress.getLocalHost(),15123);
System.out.println("Accepted connection : " + socket);
File transferFile = new File ("c:/Files Sockets/1.txt");
byte [] bytearray = new byte (int)transferFile.length()];
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray,0,bytearray.length);
OutputStream os = socket.getOutputStream();
System.out.println("Sending Files...");
os.write(bytearray,0,bytearray.length);
os.flush();
socket.close();
System.out.println("File transfer complete");
}
}