【问题标题】:java send file using socketsjava使用套接字发送文件
【发布时间】:2012-11-13 09:18:35
【问题描述】:

我正在尝试使用 Java 将文件从一台计算机发送到另一台计算机。我已经编写了下面的代码,如果发送者和接收者都在同一台计算机上启动,但如果它们在不同的机器上工作,则接收文件大小大于原始文件并且已损坏。

注意:我正在尝试传输最大 10 MB 的文件。

我该如何解决这个问题?

发件人:

ServerSocket server_socket = new ServerSocket(8989);
File myFile = new File(myPath);

Socket socket = server_socket.accept();
int count;
byte[] buffer = new byte[1024];

OutputStream out = socket.getOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(myFile));
while ((count = in.read(buffer)) > 0) {
     out.write(buffer, 0, count);
     out.flush();
}
socket.close();

接收者:

Socket socket = new Socket(address, 8989);
FileOutputStream fos = new FileOutputStream(anotherPath);
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int count;
InputStream in = socket.getInputStream();
while((count=in.read(buffer)) >0){
    fos.write(buffer);
}
fos.close();
socket.close();

【问题讨论】:

  • 我已经使用此功能发送和接收文件,但我不想关闭套接字,因为我必须使用套接字执行一些其他功能,但如果我不关闭 sock 文件接收不是得到完整的解决方案是什么

标签: java sockets network-programming


【解决方案1】:

请记住,in.read(buffer) 不一定会用新数据填满整个缓冲区。因此,您应该确保不要写入整个缓冲区。改变

while((count=in.read(buffer)) >0){
    fos.write(buffer);
}

while((count=in.read(buffer)) >0){
    fos.write(buffer, 0, count);
}

【讨论】:

    【解决方案2】:

    在客户端,您写入 最多 count 字节并发送它们:

    while ((count = in.read(buffer)) > 0) {
      out.write(buffer, 0, count);
    

    在服务器端,您读取 最多 count 字节 - 但随后您将整个缓冲区写入文件!

    while((count=in.read(buffer)) > 0){
      fos.write(buffer);
    

    只需将其更改为:

    fos.write(buffer, 0, count);
    

    你会很安全。顺便说一句,您的程序还有另一个小错误:read() 可以返回0,这并不意味着InputStream 结束。请改用>=

    count = in.read(buffer)) >= 0
    

    您是否考虑过来自 Apache Commons 的 IOUtils.copy(InputStream, OutputStream)?它会将您的整个 while 循环减少到:

    OutputStream out = socket.getOutputStream();
    InputStream in = new FileInputStream(myFile);
    IOUtils.copy(in, out);
    socket.close();
    

    要编写的代码更少,要测试的代码更少。并且缓冲是在内部完成的。

    【讨论】:

    • @Vamshi。如果您使用的是 IOUtils,那么可以,因为它实现了自己的缓冲。
    【解决方案3】:

    发件人

    Socket sock = new Socket("127.0.0.1", 5991);
            System.out.println("Connecting.........");
            File myFile = new File("/root/qrcode/");
            File[] files = myFile.listFiles();
           OutputStream os = sock.getOutputStream();
            BufferedOutputStream bos = new BufferedOutputStream(os);
                                DataOutputStream dos = new DataOutputStream(bos);
    
                                dos.writeInt(files.length);
                                long totalBytesRead = 0;
                                int percentCompleted = 0;
                                for(File file : files)
                                {
                                         long length = file.length();
                                         dos.writeLong(length);
    
                                         String name = file.getName();
                                         dos.writeUTF(name);
    
                                         FileInputStream fis = new FileInputStream(file);
                                         BufferedInputStream bis = new BufferedInputStream(fis);
    
                                         int theByte = 0;
                                         while((theByte = bis.read()) != -1)
                                         {
                                            totalBytesRead += theByte;
    
    
                                            bos.write(theByte);
                                         }
                                        //  System.out.println("file read");
                                         bis.close();
                                     }
    
                                    dos.close();
    
    
            //Closing socket  
            sock.close();
    

    接收者

    ServerSocket serverSocket = new ServerSocket(5991);  
    
        while(true) {  
            Socket clientSocket = null; 
            System.out.println("Starting...");
            clientSocket = serverSocket.accept();  
    
            InputStream in = clientSocket.getInputStream(); //used
    
            BufferedInputStream bis = new BufferedInputStream(in);
    
            String dirPath  ;
            dirPath = "/root/NewFolder";
    
            try{
                DataInputStream dis = new DataInputStream(bis);
    
                int filesCount = dis.readInt();
                File[] files = new File[filesCount];
                long f_l = 0;
                int count =0 ;
                long totalBytesRead = 0;
                int percentCompleted = 0;
    
                for(int i = 0; i < filesCount; i++)
                {
                    long fileLength = dis.readLong();
                    String fileName = dis.readUTF();
    
                    f_l = f_l +fileLength;
                    files[i] = new File(dirPath + "/" + fileName);
    
                    FileOutputStream fos = new FileOutputStream(files[i]);
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
    
                    int tot = 0;
                    for(int j = 0; j < fileLength; j++) {
    
                        bos.write(bis.read());
                    }
    
                    bos.close();
    
                }
    
            }catch(Exception ex)
            {
                System.out.println("error in socket programming ");
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      • 2016-10-06
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多