简体   繁体   中英

Java socket server client to client file transfer

I'm not sure if what I'm trying to do is possible. I want a socket server to run, multiple clients can connect to it. Client A drags and drops a file onto his GUI and client B gets a popup asking if he wants to receive the file. If agreed client A starts uploading the file and client B starts downloading the file directly. Is this possible? should the file first be transferred to the server? If I send a file to the server it works, but when I try to send a file to client BI get the following:

java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:579)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.<init>(Socket.java:425)
    at java.net.Socket.<init>(Socket.java:241)

here is the upload class:

public Upload(String addr, int port, File filepath, OpenChatFrame frame) {
        super();
        try {
            file = filepath;
            ui = frame;
            socket = new Socket(InetAddress.getByName(addr), port);
            Out = socket.getOutputStream();
            In = new FileInputStream(filepath);
            length = file.length();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            byte[] buffer = new byte[1024];

            int count;

            ui.jProgressBar1.setMaximum((int) length);

            while ((count = In.read(buffer)) >= 0) {
                Out.write(buffer, 0, count);
                bytes += count;
                ui.jProgressBar1.setValue(bytes);

            }
            Out.flush();


            if (In != null) {
                In.close();
            }
            if (Out != null) {
                Out.close();
            }
            if (socket != null) {
                socket.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

and here is the download class:

public Download(String saveTo, OpenChatFrame ui) {
    try {
        server = new ServerSocket(0);
        port = server.getLocalPort();
        this.saveTo = saveTo;
        this.ui = ui;
    } catch (IOException ex) {
        //TODO: catch
    }
}

@Override
public void run() {
    try {
        socket = server.accept();
        System.out.println("Download : " + socket.getRemoteSocketAddress());

        In = socket.getInputStream();
        Out = new FileOutputStream(saveTo);

        byte[] buffer = new byte[1024];
        int count;

        while ((count = In.read(buffer)) >= 0) {
            Out.write(buffer, 0, count);
        }

        Out.flush();

        File physicalFile = new File(saveTo);
        System.out.println("FILE FILENAME: " + physicalFile.getName());
        System.out.println("saveTo: " + saveTo);


        if (Out != null) {
            Out.close();
        }
        if (In != null) {
            In.close();
        }
        if (socket != null) {
            socket.close();
        }
    } catch (Exception ex) {
        //TODO: catch
    }
}

I want a socket server to run, multiple clients can connect to it. Client A drags and drops a file onto his GUI and client B gets a popup asking if he wants to receive the file. If agreed client A starts uploading the file and client B starts downloading the file directly. Is this possible? should the file first be transferred to the server?

Yes it is possible, if the circumstances allow it.

Assuming that the client A initiates the Socket connection, then client B's IP address must be addressable by client A. If client B has a public IP address, or a private IP address that client A's network has a route to, then you are OK. However, client B has a private IP address and client A cannot route to it, then it cannot work, and you would need a public server (accessible to both) to relay the data.

The other thing that is required is that there are no firewalls blocking connections from client A to client B on the port that they are trying to use.


Your partial stacktrace seems to be from the initiating client (client A), and indicates that the connection attempt is not getting through. Given the nature of the exception, I think that most likely explanation is that there is a firewall blocking the connection.

(If this was a routing problem, or if the server wasn't listening on the designated port, you would see different exceptions ... )


Asides:

  1. It is bad style to start variable names with an uppercase letter; eg In and Out . The style rules say that In and Out ought to be class names.

  2. The terms "upload" and "download" are not normally used to describe a "peer-to-peer" transfer; eg between two clients.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM