Receiving multiple errors on the socket Java - java

I am trying to create File Transfer system by using socket. My code used to work properly before I started sending a String fileName from server to Client to have the files in same name. Now, whenever I try to send file, it keeps giving me different error in client and server.
Server side code:
public void soc_server() throws IOException {
long time = System.currentTimeMillis();
long totalSent = 0;
ServerSocket servsock = null;
Socket sock = null;
PrintWriter pw = null;
FileInputStream fileInputStream = null;
try {
servsock = new ServerSocket(55000);
sock = servsock.accept();
System.out.println("Hello Server");
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the file name or file path");
String s = sc.nextLine();
sc.close();
File file = new File(s);
if (file.exists())
System.out.println("File found");
else
System.out.println("File not found");
OutputStream out = sock.getOutputStream();
pw = new PrintWriter(sock.getOutputStream(), true);
pw.print(s);
fileInputStream = new FileInputStream(s);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
if (bytesRead > 0) {
out.write(buffer, 0, bytesRead);
totalSent += bytesRead;
System.out.println("sent " + (totalSent / 1024) + " KB "
+ ((System.currentTimeMillis() - time) / 1000)
+ " sec");
}
}
} catch (Exception e) {
System.out.println("exception " + e);
} finally {
sock.close();
pw.close();
servsock.close();
fileInputStream.close();
System.out.println("Sent " + (totalSent / 1024) + " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000) + " seconds");
}
}
Client Side code:
public void soc_client() throws Exception {
long time = System.currentTimeMillis();
long totalRecieved = 0;
Socket sock = null;
InputStream in = null;
BufferedReader br = null;
FileOutputStream fileOutputStream = null;
try {
sock = new Socket("172.16.27.106", 55000);
System.out.println("Hello Client");
in = sock.getInputStream();
br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
File outputFile = new File(fileName + "");
fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
totalRecieved += bytesRead;
System.out.println("Recieved " + (totalRecieved / 1024)
+ " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000)
+ " seconds");
}
} catch (Exception e) {
System.out.println("Exception " + e);
} finally {
br.close(); // CLOSING BufferedReader
fileOutputStream.close();
sock.close();
System.out.println("Recieved " + totalRecieved + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}
Exceptions:
Client Side:
Exception java.io.FileNotFoundException: Invalid file path
Exception: java.lang.NullPointerException
Exception in thread "main" java.io.FileNotFoundException: Invalid file path
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at Client.soc_client(Client.java:25)
at Index.main(Index.java:24)
Server Side:
Exception java.net.SocketException: Connection reset
Exception: java.util.NoSuchElementException
Exception java.net.SocketException: Broken pipe
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at Server.soc_server(Server.java:59)
at Index.main(Index.java:21)
The file I am trying to send is the same directory (Desktop) from which I am compiling the class.
Thank you.

Try to give file name directly in the path at client side.
File outputFile = new File("yourfile.txt");
and then send it to server.
Because of exception FileNotFound at client side , you are closing the the stream at finaly block.
As you are closing the stream of client side, the server side does not recognize the stream from which it is reading hence giving Connection reset exception.
As no stream is there for reading data at server side, you are getting NoSuchElement exception
EDIT
Another thing is, you are not flushing the stream after writing to client,
So do pw.flush(); after pw.print(s) and out.write()

Related

How to make in java an http post returning binary data using plain Sockets

Because some restrictions, I have to use plain Java sockets to download a file published in a http web site. This is how i am reading the response:
String serverIp = "192....";
int serverPort = 3000;
String url = "/path/to/file";
Socket socket = new Socket(serverIp, serverPort);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String postContent = "content";
writer.write("POST " + url + " HTTP/1.0\r\n");
writer.write("Content-length: " + postContent.length() + "\r\n");
writer.write("\r\n");
writer.write(postContent);
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
if (!line.trim().equals("")) {
//Process header
} else {
break;
}
}
int intChar = -1;
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((intChar = reader.read()) >= 0) {
out.write(intChar);
}
byte[] byteArray = out.toByteArray();
File outFile = new File("myfile.zip");
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
fileOutputStream.write(byteArray);
fileOutputStream.close();
Every thing works fine, but the file myfile.zip is saved inconsistent. If I use unzip to uncompress the file, I get the error:
Archive: myfile.zip
error [myfile.zip]: missing 55053 bytes in zipfile
(attempting to process anyway)
error [myfile.zip]: start of central directory not found;
zipfile corrupt.
(please check that you have transferred or created the zipfile in the
appropriate BINARY mode and that you have compiled UnZip properly)
When I use curl to do the http post, myfile.zip download consistent and I can open it.
Any light?
Thanks guys. I used the suggestion of
President James K. Polk to write the following solution:
String serverIp = "192....";
int serverPort = 3000;
String url = "/path/to/file";
Socket socket = new Socket(serverIp, serverPort);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String postContent = "content";
writer.write("POST " + url + " HTTP/1.0\r\n");
writer.write("Content-length: " + postContent.length() + "\r\n");
writer.write("\r\n");
writer.write(postContent);
writer.flush();
DataInputStream reader = new DataInputStream(socket.getInputStream());
int c = -1;
StringBuilder header = new StringBuilder();
while ((c = reader.read()) >= 0) {
header.append((char) c);
if (header.length() > 4 && header.substring(header.length() - 4).equals("\r\n\r\n")) {
break;
}
}
File outFile = new File("myfile.zip");
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
while ((c = reader.read()) >= 0) {
fileOutputStream.write(c);
}
reader.close();
fileOutputStream.close();

Socket closed exception when trying to transfer a file

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))

File Transfer malformed input

Currently trying to have the server send a file to the client.
I'm able to see the file being created in the client directory, but it won't send all the bytes. Sometimes its 90% of the bytes, and sometimes its not even 10 bytes.
I keep getting a message from the terminal window saying: "malformed input around byte...."
Here's the Server code for this section:
String cMessage;
DataInputStream input= new DataInputStream( remote_socket.getInputStream() );
File filename = new File(cMessage);
try {
input = new DataInputStream(new FileInputStream(filename));
DataOutputStream out = new DataOutputStream(remote_socket.getOutputStream());
byte[] buffer = new byte[(int) filename.length()];
int count;
while((count = input.read(buffer)) >0){
out.write(buffer, 0, count);
}
System.out.println("Sending " + cMessage + " that is " + filename.length());
out.flush();
} catch (IOException e) {
System.out.println(e + "......");
e.printStackTrace();
}
Output for the Server when running looks like:
Sending test.png that is 723915
Here's the Client for this section:
try {
BufferedReader reader= new BufferedReader(
new InputStreamReader(System.in) );
String message;
BufferedReader fileMessageReader= new BufferedReader(
new InputStreamReader(System.in) );
String fileMessage;
DataOutputStream output= new DataOutputStream(this.client_socket.getOutputStream() );
DataInputStream input = new DataInputStream(this.client_socket.getInputStream());
while(true) {
while( (message = reader.readLine()) != null ) {
System.out.println("1. For a text message. 2. For a file");
if (message.equals("2")) {
System.out.println("Name of file?");
fileMessage = fileMessageReader.readLine();
output.writeUTF(fileMessage);
try {
File filename = new File(fileMessage);
DataOutputStream fileOutput = new DataOutputStream(new FileOutputStream(filename));
byte[] buffer = new byte[1024];
int count;
while((count = input.read(buffer)) >0){
fileOutput.write(buffer, 0, count);
}
fileOutput.flush();
fileOutput.close();
} catch (IOException e) {
System.out.println(e + "...");
}
} else {
output.writeUTF( message );
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
while ((c = input.read()) != -1) {
output.write(c);
}
This piece is killing it. If you read javadoc carefully, rather than just checking method signature, you will see that read() reads a single byte from the input (it returns int only to be able to signal end of stream with -1). So you read byte as int, no big deal, but then you blindly write aforementioned int (4 bytes) into the output stream.
You should use read(byte[] b) instead and then write the whole array (or only part of it that was read in the last round).

FTP server build in java but listing it's files

How do I make the files in the server appear in a list and appear a number behind it and press its number and download by inserting its number?
The point is trading files with my self that point I can but listing the files that I have in the directory I cant, I can already download files (thats the main point)
int porto = 21;
String IP = "x.x.x.x";
public Client() {
String destinyfile = "directory";
try {
Socket MyClient = new Socket(IP, porto);
DataInputStream input = new DataInputStream(MyClient.getInputStream());
DataOutputStream output = new DataOutputStream(MyClient.getOutputStream());
System.out.println(input.readUTF());
String arquivo = JOptionPane.showInputDialog("Insert the name of the file");
output.writeUTF(arquivo);
ObjectInputStream in = new ObjectInputStream(MyClient.getInputStream());
String fileName = in.readUTF();
if(fileName != null){
long size = in.readLong();
System.out.println("Processing the file: " + fileName + " - "+ size + " bytes.");
File file = new File(destinyfile);
if(file.exists() == false){
file.mkdir();
}
FileOutputStream fos = new FileOutputStream(caminhoDestino + fileName);
byte[] buf = new byte[4096];
while (true) {
int len = in.read(buf);
if (len == -1)
break;
fos.write(buf, 0, len);
}
fos.flush();
fos.close();
}
System.out.println(input.readUTF());
MyClient.close();
} catch (Exception e) {
Server
int port = 21;
public Servidor() {
try {
ServerSocket ss = new ServerSocket(port);
String caminho = "directory";
while (true) {
System.out.println("Waiting user.");
Socket socket = ss.accept();
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
output.writeUTF("Welcome");
String arq = input.readUTF();
System.out.println("File: " + arq);
File file = new File(caminho + arq);
if(file.exists()){
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("Transfering file: " + file.getName());
out.writeUTF(file.getName());
out.writeLong(file.length());
FileInputStream filein = new FileInputStream(file);
byte[] buf = new byte[4096];
while (true) {
int len = filein.read(buf);
if (len == -1)
break;
out.write(buf, 0, len);
}
out.close();
output.writeUTF("File Sent:");
}else{
output.writeUTF("File doesnt exist!");
}
ss.close();
}
} catch (Exception e) {
If you create a File object for the parent directory of the files you want to list, you can call that object's listFiles() to get an array of File objects in that directory.
E.g.
File parent = new File("/data/folder/");
for (File child : parent.listFiles()) {
System.out.println(child.getName());
}

FTP server hanging when transferring file over socket

I'm making a simple FTP server in java. I have everything working when I test it locally (running both the server and client on my own machine). When I run the server and client on two different remote machines, however, the client hangs somewhere shortly after it receives the "150 File status okay" message from the server. I can't understand why it works fine in one location but not the other. Here is the relevant code:
Server (sending the file):
FileInputStream input = null;
try {
input = new FileInputStream(filePath);
} catch (FileNotFoundException e) {
out.writeBytes("550 File not found or access denied.\r\n");
}
out.writeBytes("150 File status okay.\r\n");
// TCP CONNECT
DataOutputStream outToClient_d = null;
Socket clientSocket1 = null;
try {
ipAddress = ipAddress.substring(0,
ipAddress.length() - 1);
clientSocket1 = new Socket(ipAddress,
portNumber);
outToClient_d = new DataOutputStream(
clientSocket1.getOutputStream());
}
catch (UnknownHostException e) {
out.writeBytes("425 Can not open data connection.\r\n");
}
byte[] buf = new byte[2048];
int len;
while ((len = input.read(buf)) > 0) {
outToClient_d.write(buf, 0, len);
}
input.close();
out.writeBytes("250 Requested file action completed.\r\n");
clientSocket1.close();
outToClient_d.close();
Client (saving file into /retr_files):
InputStream inFromServer_d = null;
if (welcomeSocket != null) {
if (!welcomeSocket.isClosed()) {
welcomeSocket.close();
}
}
try {
welcomeSocket = new ServerSocket(port);
System.out.print("PORT " + myIP + "," + num1 + "," + num2 + "\r\n");
out.writeBytes("PORT " + myIP + "," + num1 + "," + num2 + "\r\n");
System.out.print(parseReply(getResponse()));
System.out.print("RETR " + pathname + "\r\n");
out.writeBytes("RETR " + pathname + "\r\n");
String reply = parseReply(getResponse());
if (reply.charAt(10) == '1') {
System.out.print(reply);
System.out.print(parseReply(getResponse()));
try {
clientSocket_d = welcomeSocket.accept();
} catch (IOException e) {
System.out
.print("GET failed, FTP-data port not allocated.\r\n");
System.exit(-1);
}
inFromServer_d = clientSocket_d.getInputStream();
// READ
InputStream input = inFromServer_d;
OutputStream output = new FileOutputStream("retr_files/file"
+ retrCnt);
byte[] buf = new byte[2048];
int len;
while ((len = input.read(buf)) > 0) {
output.write(buf, 0, len);
}
input.close();
output.close();
clientSocket_d.close();
} else {
System.out.print(reply);
}
} catch (IOException e) {
System.out.print("GET failed, FTP-data port not allocated.\r\n");
System.exit(-1);
}
Any help is appreciated!
I would guess there is a firewall between the client and server blocking the reverse connection from the server to the client. this problem is the reason that people typically use "passive" transfers instead of "active" transfers these days.

Categories