【问题标题】:Send File From Python Server to Java Client将文件从 Python 服务器发送到 Java 客户端
【发布时间】:2018-06-18 00:07:34
【问题描述】:

我正在尝试通过 TCP 套接字将文件从 Python 服务器发送到 Java 客户端。这是我目前所拥有的:

Java客户端(注意所有的文件传输代码都在getFile()方法中):

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();
        }

    }
}

还有 Python 服务器:

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

我能够成功地在服务器和客户端之间创建一个消息传递程序,它们可以在其中相互传递字符串。但是,我一直无法通过网络传输文件。

看来 Python 服务器正在正确发送字节,所以 Java 端似乎是问题所在。特别是 while 循环:while((counter = din.read(buffer, 0, buffer.length)) != -1) 一直在输出-1,因此文件的写入实际上从未发生。

提前感谢您的帮助!

【问题讨论】:

  • Java 端应该有某种等待逻辑。你向 python 服务器发送一个请求以获取文件名,然后立即尝试开始读取响应,如果没有得到任何内容就放弃。
  • 哦,我明白了,这就是正在发生的事情。最好的等待方式是什么?我认为只是睡觉不是最好的主意
  • 我认为实现这一点的最佳方法是拥有一个共享的“流结束指示器”,它可以用来告诉 java 服务器整个文件已发送过来。在您的情况下,这可能只是一个特定的字符串。尝试继续从流中读取,直到您读取此指示器,或直到经过特定时间。
  • 谢谢,我会按照这个协议实现一些东西,并在完成后发布一个完成的版本供其他人参考。
  • 这个问题可能会有所帮助,请记住,有很多不同的策略来处理您正在尝试做的事情。 stackoverflow.com/questions/5562370/…

标签: java python sockets client-server file-transfer


【解决方案1】:

供其他人参考,这就是我最终得到它的方式。

服务器:

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

客户:

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();
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 2013-02-05
    • 2015-05-02
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多