I am trying to transfer a file from server to client using Java and TCP, however on the client-side I am getting a socket closed exception, whereas the server has no errors when attempting to transfer the file. I am confused about this error because I did not close the socket before trying to read from it. The server accepts the connection and sends the file, but the client gets that error. Any suggestion?
The error is:
java.net.SocketException: Socket closed
Server thread's run function:
public void run() {
System.out.println("Service thread running for client at " + socket.getInetAddress() + " on port " + socket.getPort());
try {
File file = new File("hank.txt");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = socket.getOutputStream();
byte[] contents;
long fileLength = file.length();
long current = 0;
long start = System.nanoTime();
while(current!=fileLength) {
int size = 1000;
if(fileLength - current >= size) {
current += size;
}
else {
size = (int)(fileLength - current);
current = fileLength;
}
contents = new byte[size];
bis.read(contents,0,size);
os.write(contents);
System.out.println("sending file..." + (current*100)/fileLength+"% complete!");
}
os.flush();
this.socket.close();
}catch(Exception e) {
e.printStackTrace();
}
}
Client receiving the file code:
System.out.println("Going to get the file...");
socket = new Socket(response.getIP().substring(1), response.getPort());
byte[] contents = new byte[10000];
FileOutputStream fos = new FileOutputStream("hank.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
InputStream in = socket.getInputStream();
int bytesRead = 0;
System.out.println("Starting to read file...");
while((bytesRead = is.read(contents))!=-1) { //the error points to this lin
bos.write(contents,0,bytesRead);
}
bos.flush();
bos.close();
in.close();
//
socket.close();
Input stream for this socket is available in variable in
InputStream in = socket.getInputStream();
So
Change is.read(contents)) to in.read(contents))
Related
I am having trouble converse over socket using writeUTF("String") to client listen to the message using readUTF().
Up to now it worked as I wanted. However after adding codes for receiving file from the client i am not able to send any massage to the client. The code is the followings. It has been days to figure it out... Can anyone help me solve this issue? I appreciate your inputs :-)
// Client.java
String ack = in.readUTF();
println(ack); // "How do you do?"
String aack = in.readUTF();
println(aack); // HANGING FOREVER
// Server.java
Socket server = serverSocket.accept();
DataInputStream in = new DataInputStream(server.getInputStream());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
// CAN SEND MESSAGES
out.writeUTF("How do you do? "+ "\r\n");
out.flush();
// AFTER THIS SEGMENT CANNOT WRITE TO CLIENT ANYMORE
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
byte [] byteArray = new byte [FILE_SIZE];
InputStream is = server.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(byteArray,0,byteArray.length);
current = bytesRead;
do {
bytesRead =
is.read(byteArray, current, (byteArray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(byteArray, 0 , current);
bos.flush();
System.out.println("File " + FILE_TO_RECEIVED
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
}
// WORKS ALRIGHT UP TO THIS PART
// PROBLEM BEGINS...
// CANNOT
// SEND MASSAGE ANYMORE
// CLIENT WAIT FOR MSG HANGING FOREVER
out.writeUTF("Can you hear?"+ "\r\n");
out.flush();
I'd recommend that you use an OutputStreamWriter, like
OutputStream out = ...;
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, "utf-16"));
I am transferring the file by using socket programming in android
the file transferred successfully but when i open that file at client side it does not contain any data in that it contains 0 byte data
My client side code goes here:
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Abstract.docx");
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);
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
long start = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
socket.close();
and My server side code goes here
while (true) {
Socket socket = serverSocket.accept();
////////////////////////////////
File myfile=new File("/storage/sdcard0/Abstract.docx");
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.........");
msg.setText("Sending 123.exe..........");
os.write(mybytearray,0,mybytearray.length);
os.flush();
socket.close();
//////////////////////////////////////////////////////
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
socket, count);
socketServerReplyThread.run();
}
I am running it on my phones not on emulator
im having a trouble here, here i built this Socket server to download files, it downloades the files inside of a folder, but it doesnt download a specified file name an returns null, could you guys help me where should i change in this server to do so?
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
String Request = (String) sInput.readObject();
System.out.println("request is:"+Request);
String[] todoname=Request.split("\\#reza-hp");
String name=todoname[0];
System.out.println("Connecting...");
File filcheck = new File("D://Users//ProfileImages//"+name+"
//"+"ProfileImage,imagechange_1,"+name+",.jpg");
System.out.println(filcheck);
if (filcheck.exists()){
fil = new File("D://Users//ProfileImages//"+name+"
//"+"ProfileImage,imagechange_1,"+name+",.jpg");
}else{
fil = new File("D://Users//Default//");
}
System.out.println(fil);
File[] Files=fil.listFiles();
System.out.println(Files);
for (int count=0;count < Files.length;count ++){
System.out.println(Files[count].getName());
}
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeInt(Files.length);
for (int count=0;count<Files.length;count ++){
dos.writeUTF(Files[count].getName());
}
for (int count=0;count<Files.length;count ++){
int filesize = (int) Files[count].length();
dos.writeInt(filesize);
}
for (int count=0;count<Files.length;count ++){
int filesize = (int) Files[count].length();
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(Files[count].toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length); //This line is important
dos.write(buffer, 0, buffer.length);
fis.close();
dos.flush();
//close socket connection
// socket.close();
}
// Toast.makeText(getApplicationContext(),"Transfer file is
completed!!", Toast.LENGTH_LONG).show();
dos.close();
os.close();
//socket.close();
thanks
Well fixed it , here i post the singe file downloader, and in the question is the File's containing's download from any type,image,music,video , both are very viable for who ever needs to use, good luck.
String Type;
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
// my unique id (easier for deconnection)
int id;
// Constructore
ClientThread(Socket socket) throws InterruptedException {
// a unique id
id = ++uniqueId;
this.socket = socket;
/* Creating both Data Stream */
System.out.println("Thread trying to create Object Input/Output
Streams");
while (!jobdone){
try
{
// create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
String Request = (String) sInput.readObject();
System.out.println("request is:"+Request);
String[] todoname=Request.split("\\#reza-hp");
String name=todoname[0];
System.out.println("Connecting...");
File filcheck = new File("D://Users//ProfileImages//"+name+"
//"+"ProfileImage,imagechange_1,"+name+",.jpg");
System.out.println(filcheck);
if (filcheck.exists()){
fil = new File("D://Users//ProfileImages//"+name+"
//"+"ProfileImage,imagechange_1,"+name+",.jpg");
}else{
fil = new File("D://Users//Default//");
}
System.out.println(fil);
// File[] Files=fil.listFiles();
// for (int count=0;count < Files.length;count ++){
System.out.println(fil.getName());
// }
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeInt(1);
// for (int count=0;count<Files.length;count ++){
dos.writeUTF(fil.getName());
// }
// for (int count=0;count<Files.length;count ++){
int filesize = (int) fil.length();
dos.writeInt(filesize);
// }
// for (int count=0;count<Files.length;count ++){
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(fil.toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length); //This line is important
dos.write(buffer, 0, buffer.length);
fis.close();
dos.flush();
//close socket connection
// socket.close();
// Toast.makeText(getApplicationContext(),"Transfer file is
completed!!", Toast.LENGTH_LONG).show();
dos.close();
os.close();
//socket.close();
}
I have a server client file transfer program which works fine in java .but i copied it and changed the file location d:/ to environm.....
The problem is the filesize is lesser than sending one, hence its shown as corrupted.. Any idea .
SERVER SIDE
public class Server
{
// create socket
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
while(true)
{
ServerSocket servsock = new ServerSocket(13000);
System.out.println("Main Waiting...");
Socket socket = servsock.accept();
System.out.println("Accepted connection : " + socket);
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
long filesize = new Long(in.readLong());
System.out.println("received Size:"+filesize);
// read file name
String fname=in.readUTF();
System.out.println("server : file name: "+fname);
String prefix=fname.substring(0,fname.lastIndexOf('.')).trim();
String suffix=fname.substring(fname.lastIndexOf('.'),fname.length()).trim();
String file = prefix + suffix;
System.out.println("received name:"+file);
File f=new File("F:/Users/achu/Desktop/"+ file);// changed this in android
f.createNewFile();
// receive file
byte [] mybytearray = new byte [(int)(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 {
System.out.println("current"+current);
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(current<filesize && bytesRead >-1);
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
is.close();
socket.close();
servsock.close();
}
}
CLIENT SIDE
public class Client
{
Socket socket=new Socket("101.59.43.58",13000);
System.out.println("Connectedddd");
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
File file = new File("d:/my.pdf");
out.writeLong(file.length());
out.flush();
out.writeUTF(file.getName());
byte [] mybytearray = new byte [(int)file.length()];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
System.out.println("Send:"+mybytearray.length);
OutputStream ous = socket.getOutputStream();
System.out.println("Sending...");
ous.write(mybytearray,0,mybytearray.length);
ous.flush();
bis.close();
ous.close();
System.out.println("closing socket...");
socket.close();
}
My client can send Images normally to server, but when it comes to text files they arrive empty. Any ideas what am I doing wrong? I'd really appreciate help, because I have been trying to make this work for many days now. Thanks.
Here is the server code:
class TheServer {
public void setUp() throws IOException { // this method is called from Main class.
ServerSocket serverSocket = new ServerSocket(1991);
System.out.println("Server setup and listening...");
Socket connection = serverSocket.accept();
System.out.println("Client connect");
System.out.println("Socket is closed = " + serverSocket.isClosed());
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String str = rd.readLine();
System.out.println("Recieved: " + str);
rd.close();
InputStream is = connection.getInputStream();
int bufferSize = connection.getReceiveBufferSize();
FileOutputStream fos = new FileOutputStream("C:/" + str);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
bos.flush();
bos.close();
is.close();
connection.close();
serverSocket.close();
}
}
and here is the client code:
public class TheClient {
public void send(File file) throws UnknownHostException, IOException { // this method is called from Main class.
Socket socket = null;
String host = "127.0.0.1";
socket = new Socket(host, 1991);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
wr.write(file.getName());
wr.newLine();
wr.flush();
byte[] bytes = new byte[(int) length];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
}
You are prematurely closing BufferedReader on server side before reading all the data. This essentially closes the connection.
You should not use Reader or Writer for non-character streams like binary image data. And you should not mix BufferedReader with any other stream wrapper for the same stream since it may read as many data as it fills in buffer.