首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用java scoket在接收的文件中获取额外的字节

使用java scoket在接收的文件中获取额外的字节
EN

Stack Overflow用户
提问于 2018-10-08 06:57:20
回答 1查看 152关注 0票数 2

我用java socket实现了一个文件传输程序。在这个程序中,从客户端发送一个文件,然后将其下载到服务器。程序几乎正常工作,但问题是接收到的字节的长度总是大于从客户端发送的字节长度。例如,我从客户端发送了678888589字节,但当我在服务器上检查接收到的文件的长度时,我得到了678925260字节。出于这个原因,我在服务器端得到了不同的校验和。

下面是我的代码: Client Class:

代码语言:javascript
复制
public class Client  
{ 
    final static int ServerPort = 1234; 
    public static final int BUFFER_SIZE = 1024 * 50;
    private static byte[] buffer;

    public static void main(String args[]) throws UnknownHostException, IOException  
    { 
        Scanner scn = new Scanner(System.in);
        buffer = new byte[BUFFER_SIZE];

    for(int i=0;i<8;i++) {
        Socket s1 = new Socket(ip, ServerPort); 
        DataOutputStream dos1 = new DataOutputStream(s1.getOutputStream());
        SendMessage message = new SendMessage(s1, "test.mp4",dos1);
        Thread t = new Thread(message); 
        System.out.println("Adding this client to active client list"); 
        t.start();
    }
  }
}

class SendMessage implements Runnable{
    String file_name;
    Socket s;
    public final int BUFFER_SIZE = 1024 * 50;
    private byte[] buffer;
    DataOutputStream dos;

public SendMessage(Socket sc,String file_name,DataOutputStream dos) {
    this.file_name = file_name;
    this.s=sc;
    buffer = new byte[BUFFER_SIZE];
    this.dos = dos;
}

@Override
public void run() { 
    File file = new File(file_name);
    try {
        sendFile(file, dos);
        dos.close();
        while(true) {

        }
    } catch (IOException e1) {
        e1.printStackTrace();
    }

} 


public void sendFile(File file, DataOutputStream dos) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE+1];
    if(dos!=null&&file.exists()&&file.isFile())
    {
        FileInputStream input = new FileInputStream(file);
        dos.writeLong(file.length());

      System.out.println(file.getAbsolutePath());
        int read = 0;
        int totalLength = 0;
        while ((read = input.read(buffer)) != -1) {
            dos.write(buffer);
            totalLength +=read;
            System.out.println("length "+read);
        }
        input.close();
        System.out.println("File successfully sent! "+totalLength);
    }
}

}

服务器类

代码语言:javascript
复制
// Server class 
public class Server 
{ 

    // Vector to store active clients 
    static Vector<ClientHandler> ar = new Vector<>(); 

    // counter for clients 
    static int i = 0; 

    public static void main(String[] args) throws IOException 
    { 
        // server is listening on port 1234 
        ServerSocket ss = new ServerSocket(1234); 

        Socket s; 

        // running infinite loop for getting 
        // client request 
        while (true) 
        { 
            // Accept the incoming request 
            s = ss.accept(); 

            System.out.println("New client request received : " + s); 

            // obtain input and output streams 
            DataInputStream dis = new DataInputStream(s.getInputStream()); 
            DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 

            System.out.println("Creating a new handler for this client..."); 

            // Create a new handler object for handling this request. 
            ClientHandler mtch = new ClientHandler(s,"client " + i, dis, dos); 

            // Create a new Thread with this object. 
            Thread t = new Thread(mtch); 

            System.out.println("Adding this client to active client list"); 

            // add this client to active clients list 
            ar.add(mtch); 

            // start the thread. 
            t.start(); 

            // increment i for new client. 
            // i is used for naming only, and can be replaced 
            // by any naming scheme 
            i++; 

        } 
    } 
} 

// ClientHandler class 
class ClientHandler implements Runnable 
{ 
    Scanner scn = new Scanner(System.in); 
    private String name; 
    final DataInputStream dis; 
    final DataOutputStream dos; 
    Socket s; 
    boolean isloggedin; 
    public static final int BUFFER_SIZE = 1024*50;
    private byte[] buffer;

    // constructor 
    public ClientHandler(Socket s, String name, 
            DataInputStream dis, DataOutputStream dos) { 
        this.dis = dis; 
        this.dos = dos; 
        this.name = name; 
        this.s = s; 
        this.isloggedin=true; 
        buffer = new byte[BUFFER_SIZE];
    } 

    @Override
    public void run() { 
        String received;
        BufferedOutputStream out = null;
        String outputFile = "out_"+this.name+".mp4";
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(s.getInputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            out = new BufferedOutputStream(new FileOutputStream(outputFile));
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
//      while (true) 
//      { 
            try
            { 


                long length = -1;
                length = dis.readLong();
                if(length!=-1)System.out.println("length "+length);

//              String checkSum = dis.readUTF();
//              System.out.println(checkSum);

                int len=0;
                long totalLength = 0;

//              int len = 0;
                while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
                    out.write(buffer, 0, len);
                    totalLength+=len;
//                  if(len<BUFFER_SIZE)break;
//                  System.out.println("length "+len);
                    if(len<=0)break;
                }

                File file = new File(outputFile);

                System.out.println("total length1 "+totalLength+ " dif "+(totalLength-length));

                System.out.println("output length "+file.length());         

            } catch (IOException e) { 

                e.printStackTrace(); 
            } 

    }

    private static String checksum(String filepath, MessageDigest md) throws IOException {

        // file hashing with DigestInputStream
        try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md)) {
            while (dis.read() != -1) ; //empty loop to clear the data
            md = dis.getMessageDigest();
        }

        // bytes to hex
        StringBuilder result = new StringBuilder();
        for (byte b : md.digest()) {
            result.append(String.format("%02x", b));
        }
        return result.toString();

    }
}

如果有人能告诉我我做错了什么,那就太好了。另外,如何在服务器端验证校验和。另一个问题是服务器端代码在此块中被阻塞。

代码语言:javascript
复制
while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
    out.write(buffer, 0, len);
    System.out.println("length "+len);
    if(len<=0)break;
}

除非客户端断开连接,否则它不能中断循环。尽管该文件被正确地接收。

致以问候。

EN

回答 1

Stack Overflow用户

发布于 2018-10-08 08:04:04

您在客户端代码上犯了一个小错误。您写出的是整个缓冲区,而不是从文件中读取的内容。

代码语言:javascript
复制
        while ((read = input.read(buffer)) != -1) {
            dos.write(buffer,0,read);
            totalLength += read;
            System.out.println("length " + read);
        }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52693636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档