客户端服务器文件传输Java

时间:2012-04-12 04:32:43

标签: java sockets client-server protocols

我正在尝试使用Java编写一个应用程序,它允许我在服务器和请求文件的客户端之间传输文件。我打算用套接字来做。我的算法有点像这样:

在服务器上: 在客户端和服务器之间创建连接。 连接后找到需要发送给客户端的文件。 然后将文件大小发送给客户端。 然后发送文件分解成部分。

在客户端上 创建连接后,请求该文件。 接收文件大小,然后接受数据,直到达到文件大小。 停止。

如果我在算法的某处错了,请纠正我

3 个答案:

答案 0 :(得分:2)

这不是一个“算法”问题;你正在设计一个(简单的)协议。你所描述的听起来很合理,但实施起来太模糊了。你需要更具体。例如,您需要决定的一些事项:

  • 接收程序如何知道应该保存哪个文件名?应该通过套接字发送,还是应该只询问用户?
  • 如何传输文件大小?
    • 是字符串吗?如果是这样,它的长度如何显示? (使用空终止符?换行符?)
    • 是二进制值吗?如果是这样,有多大? (32位还是64?)什么是字节序?
  • “部分分解”是什么意思?如果您正在写入TCP套接字,则无需担心数据包边界; TCP处理这个问题。
  • 收件人是否会发回任何内容,例如成功或失败指示?
  • 整个文件传输后会发生什么?
    • 两端都应该假设必须关闭连接吗?
    • 或者您可以通过单个连接发送多个文件吗?如果是这样,发件人如何表明将跟随另一个文件?

此外,您正在向后使用术语“客户端”和“服务器”。通常,“客户端”是启动与服务器连接的机器,“服务器”是等待来自客户端的连接的机器。

答案 1 :(得分:1)

您还可以在收到文件的特定部分后从服务器添加确认, 类似于我们在HTTP协议中所拥有的,这将确保在服务器上接收到正确的文件传递。

答案 2 :(得分:0)

这是我使用的方法,它使用套接字的输入和输出流来发送和接收文件,完成后,它将自动重新启动服务器并从客户端重新连接到服务器。

服务器代码:

package app.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Functions 
{
    private static ServerSocket server;
    private static Socket socket;

    public static void startServer(int port)
    {   
        try 
        {
            server = new ServerSocket(port);
            socket = server.accept();
        }
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static void restartServer()
    {
        new Thread()
        {
            @Override
            public void run()
            {
                try 
                {
                    socket = server.accept();
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }.start();
    }

    public static void sendFile(String inputFilePath)
    {
        FileInputStream fis;
        BufferedInputStream bis;
        OutputStream os;
        BufferedOutputStream bos;
        try 
        {
            File input = new File(inputFilePath);
            fis = new FileInputStream(input);
            bis = new BufferedInputStream(fis);
            os = socket.getOutputStream();
            bos = new BufferedOutputStream(os);
            byte[] buffer = new byte[1024];
            int data;
            while(true)
            {
                data = bis.read(buffer);
                if(data != -1)
                {
                    bos.write(buffer, 0, 1024);
                }
                else
                {
                    bis.close();
                    bos.close();
                    break;
                }
            }
        } 
        catch (FileNotFoundException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
        restartServer();
    }
}

客户代码:

package app.client;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Functions 
{
    private static Socket socket;
    private static String hostName;
    private static int portNumber;

    public static void connectToServer(String host, int port)
    {
        new Thread()
        {
            @Override
            public void run()
            {
                try 
                {
                    hostName = host;
                    portNumber = port;
                    socket = new Socket(host, port);
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }.start();
    }

    private static void reconnectToServer()
    {
        try 
        {
            socket = new Socket(hostName, portNumber);
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void receiveFile(String outputFilePath)
    {
        InputStream is;
        BufferedInputStream bis;
        FileOutputStream fos;
        BufferedOutputStream bos;
        try 
        {
            File output = new File(outputFilePath);
            is = socket.getInputStream();
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(output);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[1024];
            int data;
            while(true)
            {
                data = bis.read(buffer);
                if(data != -1)
                {
                    bos.write(buffer, 0, 1024);
                }
                else
                {
                    bis.close();
                    bos.close();
                    break;
                }
            }
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
        reconnectToServer();
    }
}

此方法效果很好,我将其用于服务器和客户端文件传输程序,您所需要做的就是输入服务器主机的IP地址并选择端口号(我使用8888)。