dengndme 2013-05-02 17:32
浏览 480
已采纳

网络传输发送的文件内容大小不一致

Server端:
[code="java"]import java.net.*;
import java.io.*;

public class Server {
// 服务器监听端口
private int port;
// 文件保存路径
private String path;
// 判断server是否启动
private boolean started = false;

public static void main(String[] args) {
    new Server(8888, "E:/").listen(8888);
}

// 初始化服务器端口及文件保存路径
private Server(int port, String path) {
    this.port = port;
    this.path = path;
}

// 二进制转换为十进制
public static int b2i(byte[] b) {
    int value = 0;
    for (int i = 0; i < 4; i++) {
        int shift = (4 - 1 - i) * 8;
        value += (b[i] & 0x000000FF) << shift;
    }
    return value;
}

public static long b2l(byte[] b) {
    long s = 0;
    long s0 = b[0] & 0xff;
    long s1 = b[1] & 0xff;
    long s2 = b[2] & 0xff;
    long s3 = b[3] & 0xff;
    long s4 = b[4] & 0xff;
    long s5 = b[5] & 0xff;
    long s6 = b[6] & 0xff;
    long s7 = b[7] & 0xff;
    s1 <<= 8;
    s2 <<= 16;
    s3 <<= 24;
    s4 <<= 8 * 4;
    s5 <<= 8 * 5;
    s6 <<= 8 * 6;
    s7 <<= 8 * 7;
    s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7;
    return s;
}

// 主线程始终处于监听状态,等待客户端连接
private void listen(int port) {
    Socket s = null;
    ServerSocket ss = null;
    try {
        ss = new ServerSocket(port);
        started = true;
        System.out.println("监听端口:" + port);
        while (started) {
            s = ss.accept();
            System.out.println("A client connected!");
            new Thread(new HandleThread(s)).start();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// 处理接收文件并做相关处理的线程类
private class HandleThread implements Runnable {
    Socket s = null;

    private HandleThread(Socket s) {
        this.s = s;
    }

    public void run() {
        String name = getName(s);
        System.out.println(name);
        String isOver = getFile(name, s);
        System.out.println(isOver);
    }

    // 1、先获取文件名,并按照文件名创建相应文件壳,用于储存文件内容
    private String getName(Socket s) {
        try {
            InputStream is = s.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer1 = new byte[4];
            bis.read(buffer1);
            int name_len = b2i(buffer1);
            System.out.println("s_name_len = " + name_len);
            // 开始获取文件名
            byte[] buffer2 = new byte[name_len];
            bis.read(buffer2);
            return new String(buffer2);
        } catch (IOException e) {
            return new String("接收过程出现故障!");
        }

    }

    // 2、开始接收文件
    private String getFile(String name, Socket s) {
        InputStream is = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        File file = null;
        try {
            file = new File(path + "/" + name);
            if (!file.exists()) {
                file.createNewFile();
            }
            is = s.getInputStream();
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            byte[] bytes = new byte[8];
            bis.read(bytes);
            long size = b2l(bytes);
            System.out.println("s_size = " + size);
            byte[] buffer = new byte[1024];
            long count = 0;
            while (count < size) {
                long num = bis.read(buffer);

                bos.write(buffer);
                count = count + num;
            }
            /*
            int a = -1;
            while ((a = bis.read()) != -1) {
                bos.write(a);
            }*/
            bos.flush();
            bos.close();
            return "文件 " + file.getName() + " 大小  " + file.length()
                    + "接收完成!";

        } catch (IOException e) {
            return "接收失败";
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                    bos = null;
                }
                if (fos != null) {
                    fos.close();
                    fos = null;
                }
                if (bis != null) {
                    bis.close();
                    bis = null;
                }
                if (is != null) {
                    is.close();
                    is = null;
                }
                if (s != null) {
                    s.close();
                    s = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

}
[/code]
Client
[code="java"]import java.net.*;
import java.io.*;

public class Client {
// 服务器ip地址
private String ipAdd;
// 服务器监听端口号
private int port;
// 发送文件路径
private String path;

public static void main(String[] args) {
    new Client("127.0.0.1", 8888, "D:\\把悲伤留给自己.mp3").connect();
}

public Client(String ipAdd, int port, String path) {
    this.ipAdd = ipAdd;
    this.port = port;
    this.path = path;
}

// 连接到服务器
private void connect() {
    Socket s = null;
    OutputStream os = null;
    BufferedOutputStream bos = null;
    try {
        s = new Socket(ipAdd, port);
        os = s.getOutputStream();
        bos = new BufferedOutputStream(os);
        File file = new File(path);
        // 文件名
        String name = file.getName();
        // 文件大小
        long size = file.length();
        System.out.printf("%s%s%s%s%s", "Sending file ", name, " size ",
                size, " bytes to server...");
        // 先发送文件名到服务器
        boolean completed1 = sendName(name, bos);
        boolean completed2 = sendContent(file, bos);
        if (completed1 && completed2) {
            System.out.println("文件发送成功");
        } else {
            System.out.println("文件发送失败");
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println("文件未检测到");
    } finally {
        try {
            if (bos != null) {
                bos.close();
                bos = null;
            }
            if (os != null) {
                os.close();
                os = null;
            }
        } catch (IOException e) {

        }
    }

}

// 整型数据转换为byte数据方法
public static byte[] i2b(int i) {
    return new byte[] { (byte) ((i >> 24) & 0xFF),
            (byte) ((i >> 16) & 0xFF), (byte) ((i >> 8) & 0xFF),
            (byte) (i & 0xFF) };
}

// long类型转成byte数组

public static byte[] l2b(long number) {
    long temp = number;
    byte[] b = new byte[8];
    for (int i = 0; i < b.length; i++) {
        b[i] = new Long(temp & 0xff).byteValue();
        temp = temp >> 8; // 向右移8位
    }
    return b;
}

// 发送文件名长度以及文件名到服务器
private boolean sendName(String name, BufferedOutputStream bos) {
    byte[] buffer = name.getBytes();
    int name_len = buffer.length;
    try {
        // 这就要求文件名长度不能长于65535,当然,这显然不太可能!!!
        bos.write(i2b(name_len));
        bos.write(buffer);
        bos.flush();
        return true;
    } catch (IOException e) {
        return false;
    }

}

// 发送文件内容到服务器
private boolean sendContent(File file, BufferedOutputStream bos) {
    try {
        long size = file.length();
        // 先发送文件长度
        bos.write(l2b(size));
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] buffer = new byte[1024];
        long count = 0;
        // 一边读入,一边写出
        while (count < size) {
            long d = bis.read(buffer);
            count = count + d;
            bos.write(buffer);
        }
        bos.flush();
        return true;
    } catch (FileNotFoundException e) {
        System.out.println("未检测到发送文件!");
        return false;
    } catch (IOException e) {
        return false;
    }
}

}
[/code]

  • 写回答

1条回答 默认 最新

  • jinnianshilongnian 2013-05-02 17:46
    关注

    // 一边读入,一边写出

    while (count < size) {

    int d = bis.read(buffer);

    if(d== -1) {
    //over
    break;
    }
    count = count + d;

                bos.write(buffer, 0, d);  
            }  
    

    1024可能没写满
    write(byte[] b, int off, int len)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办