Java socket服务器客户端到客户端文件传输

时间:2014-06-12 10:53:42

标签: java sockets client serversocket

我不确定我尝试做的事情是否可行。 我想要一个套接字服务器运行,多个客户端可以连接到它。客户端A将文件拖放到他的GUI上,客户端B会弹出一个询问他是否要接收该文件的弹出窗口。如果约定的客户端A开始上传文件,则客户端B开始直接下载文件。这可能吗?该文件应该首先转移到服务器?如果我将文件发送到服务器它可以工作,但当我尝试将文件发送到客户端B时,我得到以下内容:

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)

这是上传类:

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

这是下载类:

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

1 个答案:

答案 0 :(得分:1)

  

我想要一个套接字服务器运行,多个客户端可以连接到它。客户端A将文件拖放到他的GUI上,客户端B会弹出一个询问他是否要接收该文件的弹出窗口。如果约定的客户端A开始上传文件,则客户端B开始直接下载文件。这可能吗?应该首先将文件传输到服务器吗?

是的,如果情况允许,是可能的。

假设客户端A启动套接字连接,则客户端B的IP地址必须可由客户端A寻址。如果客户端B具有公共IP地址或客户端A的网络有路由的私有IP地址,那么您没关系但是,客户端B有一个私有IP地址,客户端A无法路由到它,然后它无法工作,你需要一个公共服务器(两者都可访问)来传递数据。

另一件需要的是,没有防火墙阻止他们尝试使用的端口上从客户端A到客户端B的连接。


您的部分堆栈跟踪似乎来自发起客户端(客户端A),并指示连接尝试未通过。鉴于异常的性质,我认为最可能的解释是有防火墙阻止连接。

(如果这是路由问题,或者如果服务器没有在指定端口上侦听,您会看到不同的例外......)


旁白:

  1. 使用大写字母启动变量名称是不好的方式;例如InOut。样式规则说InOut应该是类名。

  2. 术语“上传”和“下载”通常不用于描述“点对点”转移;例如两个客户之间。