2

I have the following Server and Client codes. Client tries to transfer a File say "testprgm.txt" of Size say 2000B to Server, where it saves it as "Test.txt". The problem is I can see the transfer for bytes on both the Server and Client but when I see the size of the Test.txt file after running these codes, it is ZERO.

Server Program:

import java.io.*;
import java.net.*;

public class ServerTest {

    public static void main(String[] args) {
        System.out.println("**********Server Program**************");
        int byteRead = 0;
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            if (!serverSocket.isBound())
                System.out.println("Sever Socket not Bounded...");
            else
                System.out.println("Server Socket bounded to Port : " + serverSocket.getLocalPort());

            Socket clientSocket = serverSocket.accept();
            if (!clientSocket.isConnected())
                System.out.println("Client Socket not Connected...");
            else
                System.out.println("Client Socket Connected : " + clientSocket.getInetAddress());

            while (true) {
                InputStream in = clientSocket.getInputStream();

                OutputStream os = new FileOutputStream("<DESTINATION PATH>/Test.txt");
                byte[] byteArray = new byte[100];

                while ((byteRead = in .read(byteArray, 0, byteArray.length)) != -1) {
                    os.write(byteArray, 0, byteRead);
                    System.out.println("No. of Bytes Received : " + byteRead);
                }
                synchronized(os) {
                    os.wait(100);
                }
                os.close();
                serverSocket.close();
                //System.out.println("File Received...");
            }

        } catch (Exception e) {
            System.out.println("Server Exception : " + e.getMessage());
            e.printStackTrace();
        }
    }

}

Client Program :

import java.io.*;
import java.net.*;

public class Clientprgm {

public static void main(String[] args)
{
    Socket socket;
    try
    {
        socket = new Socket("SERVER IP ADDRESS>", 9999);            
        if(!socket.isConnected())
            System.out.println("Socket Connection Not established");
        else
            System.out.println("Socket Connection established : "+socket.getInetAddress());

        File myfile = new File("<SOURCE PATH>/testprgm.txt");       //local file path.


        if(!myfile.exists())
            System.out.println("File Not Existing.");
        else
            System.out.println("File Existing.");

        byte[] byteArray = new byte[1024];

        FileInputStream fis = new FileInputStream(myfile);
        BufferedInputStream bis = new BufferedInputStream(fis);
        OutputStream os = socket.getOutputStream();
        int trxBytes =0;
        while((trxBytes = bis.read(byteArray, 0, byteArray.length)) !=-1)
        {           
        os.write(byteArray, 0, byteArray.length);
        System.out.println("Transfering bytes : "+trxBytes );
        }
        os.flush();
        bis.close();
        socket.close();

        System.out.println("File Transfered...");
    }
    catch(Exception e)
    {
        System.out.println("Client Exception : "+e.getMessage());
    }       
}
}
4
  • 1
    Your if statements are odd. You print out a message in error conditions, but then continue progressing through your program. You should really exit your method (either with a return; or throwing an exception). Commented Jan 6, 2014 at 9:53
  • You are ignoring the fact that trxBytes might be between 1 and 99. This will corrupt the file. Commented Jan 6, 2014 at 9:55
  • @PeterLawrey Between 1 and 1024 actually. Commented Jan 6, 2014 at 9:56
  • @EJP I read new byte[100] for some reason. Commented Jan 6, 2014 at 10:02

2 Answers 2

2

I would use NIO for file transfer it's shorter and more efficient. Here's client side:

    try (SocketChannel sc = SocketChannel.open(new InetSocketAddress(
            hostaddress, 9999));
            FileChannel fc = new FileInputStream("test").getChannel()) {
        fc.transferTo(0, fc.size(), sc);
    }
    System.out.println("File Transfered...");

Server side:

    ServerSocketChannel ss = ServerSocketChannel.open();
    ss.bind(new InetSocketAddress("localhost", 9999));
    try (SocketChannel sc = ss.accept();
            FileChannel fc = new FileOutputStream("test").getChannel()) {
        fc.transferFrom(sc, 0, Long.MAX_VALUE);
    }
Sign up to request clarification or add additional context in comments.

4 Comments

I used your code on client side. But I am still getting the file with ZERO size on server, while the bytes are transferred.
You shouldn't read a socket input stream a byte at a time: it's most inefficient. transferTo() needs to be called in a loop. It isn't guaranteed to transfer the entire length in a single call.
@EJP it's not guaranteed only for non-blocking channels. FileChannel is always blocking, SocketChannel is blocking by default
@EvgeniyDorofeev It's not guaranteed at all. If you think otherwise please quote the relevant wording.
0

Your server copy loop is correct, in that it uses the count returned by read() in the write() method call. Your client copy loop should do the same. It doesn't.

In any case your protocol is based on a fallacy. read() on a socket input stream will return -1 when the peer closes the connection, and not before. So putting a loop that terminates when read() returns -1 inside another loop using the same connection cannot possibly work. It seems you are trying to send multiple files over a single connection. You need to send the length ahead of each file, and only read exactly that many bytes per file.

Or else you need to close the connection after sending a single file, and remove the outer loop in the receiver.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.