服务器套接字文件传输

3

我曾经在Java中使用服务器套接字概念来传输像图片和视频这样的文件。但是当我在客户端接收文件时,我会自定义文件名。我能否得到原始文件名?

例如:

如果从服务器端传输的文件名为“abc.txt”,我需要在客户端端看到相同的名称(不需要单独传递名称)。

在服务器端:

public class FileServer {
  public static void main (String [] args ) throws Exception {
    // create socket
    ServerSocket servsock = new ServerSocket(13267);
    while (true) {
      System.out.println("Waiting...");

      Socket sock = servsock.accept();
      System.out.println("Accepted connection : " + sock);
      OutputStream os = sock.getOutputStream();
    new FileServer().send(os);
      sock.close();
      }
    }

  public void send(OutputStream os) throws Exception{
      // sendfile
      File myFile = new File ("C:\\User\\Documents\\abc.png");
      byte [] mybytearray  = new byte [(int)myFile.length()+1];
      FileInputStream fis = new FileInputStream(myFile);
      BufferedInputStream bis = new BufferedInputStream(fis);
      bis.read(mybytearray,0,mybytearray.length);
      System.out.println("Sending...");
      os.write(mybytearray,0,mybytearray.length);
      os.flush();
  }
}

在客户端:

    public class FileClient{
  public static void main (String [] args ) throws Exception {


    long start = System.currentTimeMillis();


    // localhost for testing
    Socket sock = new Socket("127.0.0.1",13267);
    System.out.println("Connecting...");
    InputStream is = sock.getInputStream();
    // receive file
    new FileClient().receiveFile(is);
       long end = System.currentTimeMillis();
    System.out.println(end-start);

    sock.close();
  }

  public void receiveFile(InputStream is) throws Exception{
      int filesize=6022386;
      int bytesRead;
      int current = 0;
      byte [] mybytearray  = new byte [filesize];

        FileOutputStream fos = new FileOutputStream("def");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bytesRead = is.read(mybytearray,0,mybytearray.length);
        current = bytesRead;


        do {
           bytesRead =
              is.read(mybytearray, current, (mybytearray.length-current));
           if(bytesRead >= 0) current += bytesRead;
        } while(bytesRead > -1);

        bos.write(mybytearray, 0 , current);
        bos.flush();
        bos.close();
  }
}
4个回答

4

接收方要知道文件名,有两种方式:

a) 它必须假设它知道名称,因为它请求了该文件,

b) 服务器将名称作为流的一部分首先发送。

如果您发明了一种可以在不实际发送信息的情况下发送信息的方法,请告诉我,我们可以成为亿万富翁。我们可以称之为“计算机心灵感应”。


我正在将文件作为字节数组发送给客户端。请告诉我一个事情...它是否包含文件名? - Arun
如果您发送了名称,它将包含名称,否则文件不太可能包含自己的名称。 - Peter Lawrey

2

是的,只需在传输实际文件内容之前传输元数据(在您的情况下为myFile.getName()),并使客户端和服务器读取和发出该元数据。最好使用已建立的协议,例如HTTP及其Content-Disposition头。


但问题是我正在向客户端发送一个文件数组。我能否将文件的名称附加到文件的字节数组中?如果可以,请告诉我如何操作。 - Arun
@Arun,当然可以,你只需要设计一个协议。你使用了哪种序列化方法/协议?在问题中包含实际发送或接收文件的代码(<15行)将非常有帮助。 - phihag
我已经编辑了我的问题,并附上了完整的源代码。这实际上是从此问题中发布的链接中获取的。请帮助我。对于回复迟到,我很抱歉。 - Arun
1
@Arun 不是针对你,但这看起来有点像作业,所以我不会在这里提供完整的解决方案,而是指向一个教育性的解决方案(即HTTP)。您将需要设计自己的协议,其中应包括文件大小和名称。尝试以下格式:4个字节用于文件大小 4个字节的文件名长度 文件名作为byte[]。您可以使用myFile.getName().getBytes("UTF-8")将文件名转换为字节。顺便问一下:在new byte [(int)myFile.length()+1]中的+1背后的原理是什么? - phihag
哦,抱歉phihag,我尝试在代码后面向字节数组添加了一个额外的元素,但是我已经将其删除了。感谢您宝贵的建议。 - Arun

1

有一种更简单的方法可以做到这一点。只需将输入流包装在DataInputStream中,并使用诸如.writeUTF(myFile.getName())之类的方法。同样,您可以通过在DataInputStream上应用.readUTF来读取接收器上的文件名。以下是示例代码: 发送方:

FileInputStream fis = new FileInputStream(myFile);  
    BufferedInputStream bis = new BufferedInputStream(fis);
    DataInputStream dis = new DataInputStream(bis);
    OutputStream os;
    try {
        os = socket.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF(myFile.getName());  
.............////// catch exceptions

接收者:

InputStream in;
    try {
        bufferSize=socket.getReceiveBufferSize();
        in=socket.getInputStream();
        DataInputStream clientData = new DataInputStream(in);
        String fileName = clientData.readUTF();
        System.out.println(fileName);
................../////// catch exceptions


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接