Send File From Python Server to Java Client
Asked Answered
G

1

1

I am trying to send files from a Python server to Java client over a TCP socket. Here is what I have so far:

Java Client (Note that all of the file transfer code is in the getFile() method):

public class Client1
{
    private Socket socket = null;
    private FileOutputStream fos = null;
    private DataInputStream din = null;
    private PrintStream pout = null;
    private Scanner scan = null;

    public Client1(InetAddress address, int port) throws IOException
    {
        System.out.println("Initializing Client");
        socket = new Socket(address, port);
        scan = new Scanner(System.in);
        din = new DataInputStream(socket.getInputStream());
        pout = new PrintStream(socket.getOutputStream());
    }

    public void send(String msg) throws IOException
    {
        pout.print(msg);
        pout.flush();
    }

    public void closeConnections() throws IOException
    {
        // Clean up when a connection is ended
        socket.close();
        din.close();
        pout.close();
        scan.close();
    }

    // Request a specific file from the server
    public void getFile(String filename)
    {
        System.out.println("Requested File: "+filename);
        try {
            File file = new File(filename);
            // Create new file if it does not exist
            // Then request the file from server
            if(!file.exists()){
                file.createNewFile();
                System.out.println("Created New File: "+filename);
            }
            fos = new FileOutputStream(file);
            send(filename);

            // Get content in bytes and write to a file
            int counter;
            byte[] buffer = new byte[8192];
            while((counter = din.read(buffer, 0, buffer.length)) != -1)
            {
                fos.write(buffer, 0, counter);
            }                }
            fos.flush();
            fos.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

And the Python Server:

import socket

host = '127.0.0.1'
port = 5555

# Create a socket with port and host bindings
def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    return s


# Establish connection with a client
def setupConnection():
    s.listen(1)     # Allows one connection at a time
    print("Waiting for client")
    conn, addr = s.accept()
    return conn


# Send file over the network
def sendFile(filename, s):
    f = open(filename, 'rb')
    line = f.read(1024)

    print("Beginning File Transfer")
    while line:
        s.send(line)
        line = f.read(1024)
    f.close()
    print("Transfer Complete")


# Loop that sends & receives data
def dataTransfer(conn, s, mode):
    while True:
        # Send a File over the network
        filename = conn.recv(1024)
        filename = filename.decode(encoding='utf-8')
        filename.strip()
        print("Requested File: ", filename)
        sendFile(filename, s)
        break
    conn.close()


s = setupServer()
while True:
    try:
        conn = setupConnection()
        dataTransfer(conn, s, "FILE")
    except:
        break

I was able to successfully create a messaging program between the server and the client where they passed strings to one another. However, I have been unable to transfer files over the network.

It seems that the Python server is sending over the bytes properly, so the Java side seems to be the problem. Particularly the while loop: while((counter = din.read(buffer, 0, buffer.length)) != -1) has been giving an output of -1 so the writing of the file never actually takes place.

Thanks in advance for the help!

Gigantism answered 9/1, 2018 at 0:41 Comment(5)
There should be some kind of waiting logic on the Java side. You send a request to the python server to retreive a file name, and then immediately attempt to begin reading a response, and give up if nothing is retrieved.Typeset
Oh I see, so that's what is happening. What would be the best way to wait? I assume just sleeping isn't the best ideaGigantism
I think the best way to implement this is to have a shared "End of stream indicator" that can be used to tell the java server that the entire file has been sent over. In your case this could just be a specific String. Attempt to keep reading from the stream until you have read in this indicator, or until a specific amount of time has elapsed.Typeset
Thanks, I'll implement something to that accord and post a finished version for other people's reference when done.Gigantism
This question may be of help, keep in mind there are lot of different strategies of how to approach what you're trying to do. #5562870Typeset
G
1

For others reference, this is how I got it working in the end.

Server:

import socket
import select

server_addr = '127.0.0.1', 5555

# Create a socket with port and host bindings
def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created")
    try:
        s.bind(server_addr)
    except socket.error as msg:
        print(msg)
    return s


# Establish connection with a client
def setupConnection(s):
    s.listen(5)     # Allows five connections at a time
    print("Waiting for client")
    conn, addr = s.accept()
    return conn


# Get input from user
def GET():
    reply = input("Reply: ")
    return reply


def sendFile(filename, conn):
    f = open(filename, 'rb')
    line = f.read(1024)

    print("Beginning File Transfer")
    while line:
        conn.send(line)
        line = f.read(1024)
    f.close()
    print("Transfer Complete")


# Loop that sends & receives data
def dataTransfer(conn, s, mode):
    while True:
        # Send a File over the network
        if mode == "SEND":
            filename = conn.recv(1024)
            filename = filename.decode(encoding='utf-8')
            filename.strip()
            print("Requested File: ", filename)
            sendFile(filename, conn)
            # conn.send(bytes("DONE", 'utf-8'))
            break

        # Chat between client and server
        elif mode == "CHAT":
            # Receive Data
            print("Connected with: ", conn)
            data = conn.recv(1024)
            data = data.decode(encoding='utf-8')
            data.strip()
            print("Client: " + data)
            command = str(data)
            if command == "QUIT":
                print("Server disconnecting")
                s.close()
                break

            # Send reply
            reply = GET()
            conn.send(bytes(reply, 'utf-8'))

    conn.close()


sock = setupServer()
while True:
    try:
        connection = setupConnection(sock)
        dataTransfer(connection, sock, "CHAT")
    except:
        break

Client:

import java.net.*;
import java.io.*;
import java.util.Scanner;

public class ClientConnect {

    private Socket socket = null;
    private FileOutputStream fos = null;
    private DataInputStream din = null;
    private PrintStream pout = null;
    private Scanner scan = null;

    public ClientConnect(InetAddress address, int port) throws IOException
    {
        System.out.println("Initializing Client");
        socket = new Socket(address, port);
        scan = new Scanner(System.in);
        din = new DataInputStream(socket.getInputStream());
        pout = new PrintStream(socket.getOutputStream());
    }

    public void send(String msg) throws IOException
    {
        pout.print(msg);
        pout.flush();
    }

    public String recv() throws IOException
    {
        byte[] bytes = new byte[1024];
        din.read(bytes);
        String reply = new String(bytes, "UTF-8");
        System.out.println("Inside recv(): ");
        return reply;
    }

    public void closeConnections() throws IOException
    {
        // Clean up when a connection is ended
        socket.close();
        din.close();
        pout.close();
        scan.close();
    }

    public void chat() throws IOException 
    {    
        String response = "s";

        System.out.println("Initiating Chat Sequence");
        while(!response.equals("QUIT")){
            System.out.print("Client: ");
            String message = scan.nextLine();
            send(message);
            if(message.equals("QUIT"))
                break;
            response = recv();
            System.out.println("Server: " + response);
        }
        closeConnections();
    }

    // Request a specific file from the server
    public void getFile(String filename)
    {
        System.out.println("Requested File: "+filename);
        try {
            File file = new File(filename);
            // Create new file if it does not exist
            // Then request the file from server
            if(!file.exists()){
                file.createNewFile();
                System.out.println("Created New File: "+filename);
            }
            fos = new FileOutputStream(file);
            send(filename);

            // Get content in bytes and write to a file
            byte[] buffer = new byte[8192];
            for(int counter=0; (counter = din.read(buffer, 0, buffer.length)) >= 0;)
            {
                    fos.write(buffer, 0, counter);
            }
            fos.flush();
            fos.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
Gigantism answered 8/2, 2018 at 19:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.