精华内容
下载资源
问答
  • java多线程文件传输

    2010-08-10 14:29:24
    java多线程文件传输 java多线程文件传输
  • 上个礼拜,测试一个东西,就是单线程和多线程客户端与一个socket服务器连接,传输数据,哪一个更快。然后我写了一个程序,如下:服务器代码public class SocketServer {private int port;private ServerSocket ...

    上个礼拜,测试一个东西,就是单线程和多线程客户端与一个socket服务器连接,传输数据,哪一个更快。然后我写了一个程序,如下:

    服务器代码

    public class SocketServer {

    private int port;

    private ServerSocket serverSocket;

    private Date date;

    private static long startDate = 0;

    public SocketServer (int port){

    this.port = port ;

    startSend();

    }

    public static void receiveFile(Socket socket) throws IOException

    {

    byte[] inputByte = null;

    int length = 0;

    DataInputStream dis = null;

    FileOutputStream fos = null;

    DataOutputStream dos = null;

    String filePath = "D:/temp/"+"SJ"+new

    Random().nextInt(10000)+".docx";

    try {

    try {

    dis = new DataInputStream(socket.getInputStream());

    //dos = new DataOutputStream(socket.getOutputStream());

    File f = new File("D:/temp");

    if(!f.exists()){

    f.mkdir();

    }

    fos = new FileOutputStream(new

    File(filePath));

    inputByte = new

    byte[1024];

    System.out.println("开始接收数据..."+(new Date().getTime() - startDate));

    while ((length = dis.read(inputByte, 0, inputByte.length)) > 0)

    {

    fos.write(inputByte, 0, length);

    fos.flush();

    }

    //发送回执

    dos.write(inputByte);

    System.out.println("完成接收:"+filePath);

    } finally {

    if (fos != null)

    fos.close();

    if (dis != null)

    dis.close();

    if (socket != null)

    socket.close();

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    public void startSend(){

    int mark =0;

    try {

    serverSocket = new ServerSocket(port);

    System.out.println("服务器已启动,端口号为:"+port+".");

    System.out.println("正在等待客户端连接......");

    while (true) {

    try

    {

    System.out.println("开始监听...");

    Socket socket = serverSocket.accept();

    System.out.println("有链接");

    if(mark==0)

    {

    startDate = new Date().getTime();

    mark =1;

    }

    receiveFile(socket);

    long time = new Date().getTime() - startDate;

    System.out.println("总时间:"+time);

    } catch (Exception e) {

    System.out.println("服务器异常");

    e.printStackTrace();

    }

    }

    //socketAccept.close();

    } catch (Exception e)

    {

    }

    }

    }

    客户端代码:

    public void connectSocketFileTrans() throws

    IOException{

    int length = 0;

    double sumL = 0 ;

    int mark = 0;

    byte[] sendBytes = null;

    byte[] recvBytes = null;

    Socket socket = null;

    DataInputStream dis = null;

    DataOutputStream dos = null;

    FileInputStream fis = null;

    boolean bool = false;

    long startTime =0;

    long endTime = 0;

    long l = 1;

    try {

    File file = new File(fileName); //要传输的文件路径

    l = file.length();

    if(host.equals("localhost")||host.equals("127.0.0.1")){

    socket = new Socket(InetAddress.getLocalHost(),port);

    }else {

    socket = new Socket(InetAddress.getByName(host),port);

    }

    System.out.println(fileName);

    startTime = new Date().getTime();//开始设置管道,以及读写数据

    dos = new DataOutputStream(socket.getOutputStream());

    dis = new DataInputStream(socket.getInputStream());

    fis = new

    FileInputStream(file);

    sendBytes = new byte[1024];

    recvBytes = new byte[1024];

    while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0)

    {

    dos.write(sendBytes, 0, length);

    dos.flush();

    //dis.read(recvBytes, 0, recvBytes.length);

    //if(Arrays.equals(recvBytes, sendBytes))

    {

    sumL += length;

    if(mark == 0)

    {

    System.out.println(fileName+"已传输:"+((sumL/l)*100)+"%");

    mark = 1;

    }

    System.out.println(fileName+"已传输:"+((sumL/l)*100)+"%");

    }

    //else

    {

    //System.out.println("传输错误");

    }

    }

    if(sumL==l){

    bool =

    true;

    //结束管道的读写数据

    endTime = new Date().getTime();

    this.timeRun = endTime - startTime;

    System.out.println(fileName+"已传输:"+((sumL/l)*100)+"%");

    }

    }catch (Exception e) {

    System.out.println("客户端文件传输异常");

    bool = false;

    e.printStackTrace();

    } finally{

    if (dos != null)

    dos.close();

    if (fis != null)

    {

    fis.close();

    dis.read(recvBytes, 0, recvBytes.length);

    if(Arrays.equals(recvBytes, sendBytes))

    {

    sumL += length;

    if(mark == 0)

    {

    System.out.println(fileName+"已传输:"+((sumL/l)*100)+"%");

    mark = 1;

    }

    System.out.println(fileName+"已传输:"+((sumL/l)*100)+"%");

    }

    else

    {

    System.out.println("传输错误");

    }

    dis.close();

    }

    if (socket != null)

    socket.close();

    }

    System.out.println(bool?"成功":"失败");

    }

    上面都是节选的下面所用到的一部分。

    第一次测试的时候,使用最终回执,即只是在一个文件传送结束后使用回执。但是我的计算运行时间的函数写在了服务器端,当服务器开始接收一个文件的时候,记录开始时间,完全就接收到所有文件的时候,记录结束时间。这时候,在本地测试的时候,多线程竟然比单线程要快一些。

    然后,我写了带有回执的第二次测试代码,并且在客户端记录时间,当开始执行第一次发送文件之前,记录开始时间,当所有线程或者所有类都发送结束后,记录结束时间。这时候,在本地测试的时候,单线程就比多线程快了。

    后来,我做文件io测试的时候,在多次加载文件的情况下,多线程要比单线程快一些,我就误以为是第一个测试是因为文件io的原因,才使得多线程要比单线程快,但是后来我在调试的时候,发现情况并不只是这样。

    在第一个测试背景下,当我服务器开启调试的时候,等待客户端连接,客户端多线程执行,向服务器发送连接请求,将文件写入数据输出管道,即当服务器接收到连接请求,并开始记录时间的时候,客户端已经完成很大一部分数据写入管道的操作了,大概每个管道可以写入的数据为190k左右,然后管道排满之后停止写入,也就阻塞在写方法上了,此时要等待所有数据发完之后才可以继续执行。而单线程的慢的原因在于客户端在服务器开始记录时间之前,只完成了第一个文件的预读,而没有做剩余文件的预读。所以,单线程要比多线程要慢,所以这个测试是错误的。

    这个错误的原因来自于,我认为客户端的连接是阻塞在构造方法上,或者是写入数据方法上的,然而并不是这样子。实际的情况是这样,服务器开启后,阻塞在等待接收连接请求,而客户端发送连接请求,服务器接收到很多连接请求,对这些连接请求生成一个对列,然后处理第一个连接请求。而客户端方面,发送完连接请求之后,继续执行,将数据写入管道,因为没有回执,所以数据会一直写入管道,直到管道被填满,然后写方法进入阻塞状态。而此时,可能服务器端还没有计时。当服务器开始正式接收连接请求之后,客户端某线程进入连接状态,在管道中的数据会直接发送过去,然后该线程的管道写方法跳出阻塞状态开始执行,继续向管道中的写入剩余数据,直到所有数据传送完成,然后线程结束。服务器接收连接队列的下一条请求,然后重复执行上面步骤。所以第一次的计算时间的时候,多线程比单线程要少很多的文件io的时间。

    所以,在服务器端是单线程的情况下,单线程客户端要比多线程快一些。

    展开全文
  • java多线程网络传输文件
  • 利用java技术实现多线程文件传输
  • 面试题:如果使用Java开发多线程传输文件,你如何实现。(只需要说明技术和思路) BS结构 H5,文件组件标签,有多个属性,文件切割相关属性。把一个文件切割,从文件的第几个字节开始读取,读取多少字节。 服务端...

    面试题:如果使用Java开发多线程传输文件,你如何实现。(只需要说明技术和思路)

    BS结构

    H5,文件组件标签,有多个属性,文件切割相关属性。把一个文件切割,从文件的第几个字节开始读取,读取多少字节。

    服务端本身就是一个多线程,
    Commons-Fileupload

    一个进程有多个线程,一个线程有多个协程

    CS结构

    使用多线程技术和RandomAccessFile技术实现。
    多线程,提高效率使用ExecutorService线程池,优化代码。
    RandomAccessFile是随机文件读写流,打开文件,做随机读写。通过分隔文件,跳过不需要读写的字节数,进行读写操作。

    socket+IO
    java.io.RandomAccessFile 文件随机读写流

    上传:
    client:

     class ClientMain{
    	  public static void main(String[] args){
    	    Socket s = new Socket(ip, port);
    	    File file = new File(path);
    	    FileInputStream fis = new FileInputStream(file);
    	    // 文件的总体长度
    	    long length = fis.available();
                // 设置10线程上传。
    	    long point = length/10;
    	    // 让服务器创建文件
                OutputStream output = s.getOutputStream();
    	    output.write("{\"filename\"=\"xxx\"}".byteArray());
    	    // 阻塞等待,等待多线程上传结束。
    	    // 创建一个线程池,固定容量,只有10个线程。
                ExecutorService es = ExecutorServices.newFixedThreadPool(10);
    	    ArrayList fArray = new ArrayList();
    	    for(int i = 0; i < 10; i++){
    	      Socket upload = new Socket(ip, port);
    	      int index = (i * point);
    	      int endIndex = 0;
    	      if(i != 9){
    	        endIndex = (i + 1) * point;
    	      }else{
    	        endIndex = length;
    	      }
    	      Future<Object> f = 
    	        es.submit(new UpdateClient(file, index, endIndex, upload));
    	      fArray.add(f);
    	    }
    	    int flag = 10;
    	    while(flag > 0){
    	      for(Future f : fArray){
    	        try{
    		  f.get(10, TimeUnit.MILLSSECOND);
    		  flag--;
    		  fArray.remove(f);
    		}catch(Exception e){}
    	      }
    	    }
    	    // 所有的线程都执行结束了。文件上传结束。
    	    s.close();
    	  }
    	}
    	class UploadClient implements Callable{
    	  private File file; // 要上传的文件
    	  private int index; // 要读取的文件的起始下标
    	  private int endIndex; // 要读取的文件的结束下标
    	  private Socket socket; // 客户端对象
    	  public UploadClient(File file, int index, int endIndex, Socket socket){
    	    // 赋值
    	  }
    	  public Object call(){
    	    RandomAccessFile raf = new RandomAccessFile(file);
    	    raf.skipBytes(index);
    	    byte[] temp = new byte[endIndex - index];
    	    raf.read(temp, index, endIndex - index);
    	    OutputStream output = socket.getOutputStream();
    	    // 通知服务器,本次连接上传的是那一个文件,是这个文件的那一个部分。
    	    output.write("{\"filename\"=\"\",\"index\"=?,\"endIndex\"=?}".getBytes());
    	    // 通知服务器,描述信息结束,后续的都是文件内容。
    	    output.write("\n".getBytes());
    	    output.flush();
    	    output.write(temp);
    	    output.flush();
    	    raf.close();
    	    socket.close();
    
    	    return "ok";
    	  }
    	}
    

    server:

      class ServerMain{
    	  public static void main(String [] args){
    	    ServerSocket ss = new ServerSocket(port);
    	    while(true){
    	      Socket s = ss.accept();
    	      new Thread(new ServerHandler(s)).start();
    	    }
    	  }
    	}
    	class ServerHandler implements Runnable{
    	  private Socket s;
              public ServerHandler(Socket s){}
    	  public void run(){
    	    InputStream input = s.getInputStream();
    	    BufferedReader reader = new BufferedReader(input);
    	    String line = reader.readLine();
    	    // 处理字符串line,如果是{filename:xxx}, 创建文件
    	    ObjectMapper om = new ObjectMapper();
    	    Map map = om.readObject(line, Map.class);
    	    if(map.size() == 1){// 创建文件}
    	    else{// 多线程写入操作
    	      // 读取文件内容,做写入操作
                  String filename = map.get("filename");
    	      long index = map.get("index");
    	      long endIndex = map.get("endIndex");
    	      RandomAccessFile raf = new RandomAccessFile(filename, "append");
    	      raf.skipBytes(index);
    	      input.read();
    	      raf.write();
    	    }
    	  }
    	}
    
    

    迅雷

    java编写简单的Socket通信应用 实现服务端同时处理多个客户端

    java socket 多线程网络传输多个文件

    展开全文
  • 一、相关步骤如下:* 1,提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹* 2,发送文件名到服务器* 3,建立多线程的服务器* 4,读取文件名* 5,判断文件是否存在,将结果发回客户端* 6,接收结果,如果...

    一、相关步骤如下:

    * 1,提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹

    * 2,发送文件名到服务器

    * 3,建立多线程的服务器

    * 4,读取文件名

    * 5,判断文件是否存在,将结果发回客户端

    * 6,接收结果,如果存在给予提示,程序直接退出

    * 7,如果不存在,定义FileInputStream读取文件,写出到网络

    * 8,定义FileOutputStream,从网络读取数据,存储到本地

    [code]//自定义提示信息对象

    class Msg{

    String satus;

    String msg;

    File file;

    }

    public class ZuoYe {

    int num=0;

    //下载

    public void download() throws Exception {

    Scanner sc = new Scanner(System.in);

    System.out.println("是否下载??( y/n )");

    while(true) {

    if("y".equals(sc.next())) {

    System.out.println("选择以上一张图片地址");

    String urls = sc.next();

    File file = getFile(false);

    URL url = new URL(urls);

    URLConnection conn = url.openConnection();

    InputStream is = conn.getInputStream();

    FileOutputStream fos = new FileOutputStream(file);

    byte[] b = new byte[1024];

    int len ;

    while((len=is.read(b))!=-1) {

    fos.write(b, 0, len);

    }

    fos.close();

    is.close();

    System.out.println("下载完成!");

    }else {

    break;

    }

    System.out.println("继续下载??(y/n)");

    }

    System.out.println("您已退出程序");

    }

    //上传

    public String upload(File file) throws Exception {

    num++;

    System.out.println("上传中...");

    FileInputStream fis = new FileInputStream(file);

    InetAddress byName = InetAddress.getByName("127.0.0.1");

    Socket so = new Socket(byName,6666);

    OutputStream os = so.getOutputStream();

    byte[] b = new byte[1024];

    int len;

    while((len=fis.read(b))!=-1) {

    os.write(b, 0, len);

    }

    so.shutdownOutput();

    InputStream is = so.getInputStream();

    InputStreamReader Isr = new InputStreamReader(is);

    BufferedReader br = new BufferedReader(Isr);

    String url = br.readLine();

    System.out.println("第"+num+"张图片上传完成!");

    System.out.println("资源访问地址:"+url);

    os.close();

    so.close();

    fis.close();

    return url;

    }

    //获取用户输入并返回提示信息

    public Msg print(boolean b) {

    Msg msg = new Msg();

    Scanner sc = new Scanner(System.in);

    //文件路径

    System.out.println("输入路径(绝对路径)");

    String path = sc.next();

    if(path.equals("exit")) {

    msg.satus = "exit";

    msg.msg = "退出程序";

    return msg;

    }

    File dir = new File(path);

    if(!dir.isDirectory()) {

    msg.satus = "path_error";

    msg.msg = "输入的不是一个文件夹,请重新输入";

    return msg;

    };

    //文件名

    System.out.println("输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)");

    String fileName = sc.next();

    if(fileName.equals("exit")) {

    msg.satus = "exit";

    msg.msg = "退出程序";

    return msg;

    }

    if(!fileName.endsWith(".jpg")&&!fileName.endsWith(".png")) {

    msg.satus = "format_error";

    msg.msg = "文件格式不正确";

    return msg;

    }

    File file = new File(path+'/'+fileName);

    if(b) {

    if(!file.exists()) {

    msg.satus = "file_error";

    msg.msg = "文件不存在";

    return msg;

    }

    }

    msg.satus = "success";

    msg.msg = "文件可用";

    msg.file = file;

    return msg;

    }

    //获得文件对象

    public File getFile(boolean b) {

    int i=1;

    File file = null;

    while(true) {

    Msg msg = print(b);

    if("exit".equals(msg.satus)) {

    System.out.println(msg.msg);

    break;

    }else if("success".equals(msg.satus)) {

    //System.out.println("第"+ ++i +"张");

    file = msg.file;

    break;//多图去掉break

    }else {

    System.out.println(msg.msg);

    continue;

    }

    }

    return file;

    }

    //获得LinkedList多个文件对象

    public LinkedList getFiles(boolean b) {

    LinkedList list = new LinkedList<>();

    int i=1;

    File file = null;

    while(true) {

    Msg msg = print(b);

    if("exit".equals(msg.satus)) {

    System.out.println(msg.msg);

    break;

    }else if("success".equals(msg.satus)) {

    System.out.println("第"+ ++i +"张");

    file = msg.file;

    list.add(file);

    //break;//多图去掉break

    }else {

    System.out.println(msg.msg);

    continue;

    }

    }

    return list;

    }

    @Test //模拟客户端,多图上传

    public void client() throws Exception {

    Scanner sc = new Scanner(System.in);

    LinkedList list = new LinkedList<>();

    System.out.println("根据提示选择文件,输入 exit 结束选择");

    list = getFiles(true);

    //while(true) {

    //File file = getFile(true);

    //String url = upload(file);

    //download(url);

    //}

    if(!list.isEmpty()) {//循环实现多图上传,目前无效

    for(File f :list) {

    String url = upload (f);

    }

    download();

    }

    }

    @Test //模拟服务端图片上传,

    //junit 无法启动线程,只能用main方法测试

    public void server() throws IOException{

    ServerSocket ss = new ServerSocket(6666);

    while(true) {

    Socket sk = ss.accept();

    new Thread(new Server(sk)).start();

    }

    }

    }

    class Server implements Runnable{

    Socket sk;

    public Server(Socket sk) {

    super();

    this.sk = sk;

    }

    @Override

    public void run() {

    try {

    InputStream is = sk.getInputStream();

    String fname = String.valueOf(System.currentTimeMillis()/1000);

    String dir ="img";

    String path = "D:\\Work\\apache-tomcat-8.0.50\\webapps";

    String newName = path+"\\"+dir+"\\"+fname+".jpg";

    File file = new File(newName);

    FileOutputStream fos = new FileOutputStream(file);

    byte[] b = new byte[1024];

    int len;

    while((len=is.read(b))!=-1) {

    fos.write(b, 0, len);

    }

    OutputStream os = sk.getOutputStream();

    InetAddress addr = InetAddress.getLocalHost();

    String url="http://"+addr.getHostAddress()+":8080/"+dir+"/"+fname+".jpg";

    os.write(url.getBytes());

    sk.shutdownOutput();

    os.close();

    fos.close();

    is.close();

    sk.close();

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    执行效果

    根据提示选择文件,输入 exit 结束选择

    输入路径(绝对路径)

    D:/web

    输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

    1.jpg

    第2张

    输入路径(绝对路径)

    D:/web

    输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

    w.jpg

    第3张

    输入路径(绝对路径)

    d:/web

    输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

    sdss.jpg

    第4张

    输入路径(绝对路径)

    exit

    退出程序

    上传中...

    第1张图片上传完成!

    资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

    上传中...

    第2张图片上传完成!

    资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

    上传中...

    第3张图片上传完成!

    资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

    是否下载??(   y/n )

    y

    选择以上一张图片地址

    http://192.168.2.183:8080/img/1560585078.jpg

    输入路径(绝对路径)

    D:/web

    输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

    test001.jpg

    下载完成!

    继续下载??(y/n)

    y

    选择以上一张图片地址

    http://192.168.2.183:8080/img/1560585078.jpg

    输入路径(绝对路径)

    D:/web

    输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

    test002.png

    下载完成!

    继续下载??(y/n)

    n

    您已退出程序

    二、使用基于UDP的Java Socket编程,完成在线咨询功能:

    1)客户向咨询人员咨询。

    2)咨询人员给出回答。

    3)客户和咨询人员可以一直沟通,直到客户发送bye给咨询人员。

    **********在线聊天一定是多线程*********

    564a5d57e6cbf0e11a242460605eb78d.png

    [code]@Test//客户端1

    //junit无法启动线程,不知为何,main方法没问题

    public void client1() throws Exception{

    DatagramSocket send_da = new DatagramSocket();

    DatagramSocket receive_da = new DatagramSocket(1029);

    Thread t = new Thread(new Send(send_da,1025));

    t.setName("客服1:");

    t.start();

    Thread t2 = new Thread(new Receive(receive_da));

    t2.setName("客户:");

    t2.start();

    }

    @Test//客户端2

    //junit无法启动线程,不知为何,main方法没问题

    public void client2() throws SocketException{

    DatagramSocket send_da = new DatagramSocket();

    DatagramSocket receive_da = new DatagramSocket(1025);

    Thread t = new Thread(new Send(send_da,1029));

    t.setName("客户:");

    t.start();

    Thread t2 = new Thread(new Receive(receive_da));

    t2.setName("客服1:");

    t2.start();

    }

    }

    class Send implements Runnable{

    DatagramSocket ds = null;

    int port;

    public Send(DatagramSocket ds,int port) {

    super();

    this.ds = ds;

    this.port = port;

    }

    @Override

    public void run() {

    try {

    Scanner sc = new Scanner(System.in);

    while(true) {

    String line = sc.nextLine();

    byte[] b = line.getBytes();

    InetAddress byName = InetAddress.getByName("127.0.0.1");

    DatagramPacket dp = new DatagramPacket(b, 0, b.length, byName,port);

    ds.send(dp);

    if("bye".equalsIgnoreCase(line)){

    System.out.println(Thread.currentThread().getName()+"已离开....");

    }

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    class Receive implements Runnable{

    DatagramSocket ds;

    DatagramPacket dp;

    public Receive(DatagramSocket ds) {

    this.ds = ds;

    }

    @Override

    public void run() {

    try {

    while(true){

    byte[] buf = new byte[1024];

    dp = new DatagramPacket(buf, buf.length);

    ds.receive(dp);

    //String ip = dp.getAddress().getHostAddress();

    //int port = dp.getPort();

    String str = new String( dp.getData(),0,dp.getLength() );

    System.out.println(Thread.currentThread().getName()+str);

    if("bye".equalsIgnoreCase(str)){

    System.out.println(Thread.currentThread().getName()+"已离开....");

    }

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    展开全文
  • 客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的ServerSocket每次 accept 一个 socket 连接,创建一个线程用于接收客户端传来的文件。1、服务端importjava.io.BufferedInputStream...

    客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的ServerSocket每次 accept 一个 socket 连接,创建一个线程用于接收客户端传来的文件。1、服务端importjava.io.BufferedInputStream;importjava.io.BufferedOutputStream;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.FileOutputStream;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classTransferServer {private int defaultBindPort = Constants.DEFAULT_BIND_PORT; //默认监听端口号为10000

    private int tryBindTimes = 0; //初始的绑定端口的次数设定为0

    private ServerSocket serverSocket; //服务套接字等待对方的连接和文件发送

    private ExecutorService executorService; //线程池

    private final int POOL_SIZE = 4; //单个CPU的线程池大小

    /*** 不带参数的构造器,选用默认的端口号

    *@throwsException*/

    public TransferServer() throwsException{try{this.bingToServerPort(defaultBindPort);

    executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() *POOL_SIZE);

    System.out.println("开辟线程数 : " + Runtime.getRuntime().availableProcessors() *POOL_SIZE);

    }catch(Exception e) {throw new Exception("绑定端口不成功!");

    }

    }/*** 带参数的构造器,选用用户指定的端口号

    *@paramport

    *@throwsException*/

    public TransferServer(int port) throwsException{try{this.bingToServerPort(port);

    executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() *POOL_SIZE);

    }catch(Exception e) {throw new Exception("绑定端口不成功!");

    }

    }private void bingToServerPort(int port) throwsException{try{

    serverSocket= newServerSocket(port);

    System.out.println(port);

    System.out.println("服务启动!");

    }catch(Exception e) {this.tryBindTimes = this.tryBindTimes + 1;

    port= port + this.tryBindTimes;if(this.tryBindTimes >= 20){throw new Exception("您已经尝试很多次了,但是仍无法绑定到指定的端口!请重新选择绑定的默认端口号");

    }//递归绑定端口

    this.bingToServerPort(port);

    }

    }public voidservice(){

    Socket socket= null;while (true) {try{

    socket=serverSocket.accept();

    executorService.execute(newHandler(socket));

    }catch(Exception e) {

    e.printStackTrace();

    }

    }

    }class Handler implementsRunnable{privateSocket socket;publicHandler(Socket socket){this.socket =socket;

    }public voidrun() {

    System.out.println("New connection accepted " + socket.getInetAddress() + ":" +socket.getPort());

    DataInputStream dis= null;

    DataOutputStream dos= null;int bufferSize = 8192;byte[] buf = new byte[bufferSize];try{

    dis= new DataInputStream(newBufferedInputStream(socket.getInputStream()));

    String savePath= Constants.RECEIVE_FILE_PATH +dis.readUTF();long length =dis.readLong();

    dos= new DataOutputStream(new BufferedOutputStream(newFileOutputStream(savePath)));int read = 0;long passedlen = 0;while ((read = dis.read(buf)) != -1) {

    passedlen+=read;

    dos.write(buf,0, read);

    System.out.println("文件[" + savePath + "]已经接收: " + passedlen * 100L/ length + "%");

    }

    System.out.println("文件: " + savePath + "接收完成!");

    }catch(Exception e) {

    e.printStackTrace();

    System.out.println("接收文件失败!");

    }finally{try{if(dos != null){

    dos.close();

    }if(dis != null){

    dis.close();

    }if(socket != null){

    socket.close();

    }

    }catch(Exception e) {

    e.printStackTrace();

    }

    }

    }

    }public static void main(String[] args) throwsException{newTransferServer().service();

    }

    }2、客户端importjava.io.BufferedInputStream;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.net.Socket;importjava.util.ArrayList;importjava.util.Random;importjava.util.Vector;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classTransferClient {private static ArrayList fileList = new ArrayList();private String sendFilePath =Constants.SEND_FILE_PATH;/*** 带参数的构造器,用户设定需要传送文件的文件夹

    *@paramfilePath*/

    publicTransferClient(String filePath){

    getFilePath(filePath);

    }/*** 不带参数的构造器。使用默认的传送文件的文件夹*/

    publicTransferClient(){

    getFilePath(sendFilePath);

    }public voidservice(){

    ExecutorService executorService=Executors.newCachedThreadPool();

    Vector vector =getRandom(fileList.size());for(Integer integer : vector){

    String filePath=fileList.get(integer.intValue());

    executorService.execute(sendFile(filePath));

    }

    }private voidgetFilePath(String dirPath){

    File dir= newFile(dirPath);

    File[] files=dir.listFiles();if(files == null){return;

    }for(int i = 0; i < files.length; i++){if(files[i].isDirectory()){

    getFilePath(files[i].getAbsolutePath());

    }else{

    fileList.add(files[i].getAbsolutePath());

    }

    }

    }private Vector getRandom(intsize){

    Vector v = new Vector();

    Random r= newRandom();boolean b = true;while(b){int i =r.nextInt(size);if(!v.contains(i))

    v.add(i);if(v.size() ==size)

    b= false;

    }returnv;

    }private static Runnable sendFile(finalString filePath){return newRunnable(){private Socket socket = null;private String ip ="localhost";private int port = 10000;public voidrun() {

    System.out.println("开始发送文件:" +filePath);

    File file= newFile(filePath);if(createConnection()){int bufferSize = 8192;byte[] buf = new byte[bufferSize];try{

    DataInputStream fis= new DataInputStream(new BufferedInputStream(newFileInputStream(filePath)));

    DataOutputStream dos= newDataOutputStream(socket.getOutputStream());

    dos.writeUTF(file.getName());

    dos.flush();

    dos.writeLong(file.length());

    dos.flush();int read = 0;int passedlen = 0;long length = file.length(); //获得要发送文件的长度

    while ((read = fis.read(buf)) != -1) {

    passedlen+=read;

    System.out.println("已经完成文件 [" + file.getName() + "]百分比: " + passedlen * 100L/ length + "%");

    dos.write(buf,0, read);

    }

    dos.flush();

    fis.close();

    dos.close();

    socket.close();

    System.out.println("文件 " + filePath + "传输完成!");

    }catch(Exception e) {

    e.printStackTrace();

    }

    }

    }private booleancreateConnection() {try{

    socket= newSocket(ip, port);

    System.out.println("连接服务器成功!");return true;

    }catch(Exception e) {

    System.out.println("连接服务器失败!");return false;

    }

    }

    };

    }public static voidmain(String[] args){newTransferClient().service();

    }

    }3、常量类public interfaceConstants {public final static String RECEIVE_FILE_PATH = "E:\\receive\\";public final static String SEND_FILE_PATH = "E:\\send";public final static int DEFAULT_BIND_PORT = 10000;

    }

    展开全文
  • javaweb上传文件上传文件的jsp中的部分上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求1.通过form表单向后端发送请求Save改进后的代码不需要form标签,直接由控件来实现。开发人员只需要...
  • 今天来写一个简单的多线程传输,一个服务器,一个客户端传送基本数据,一个客户端传输文件 服务器线程端 package com.sheng.tetst1; //网络编程多线程 import java.io.BufferedReader; import java.io....
  • 文件夹数据库处理逻辑 public class DbFolder { ...在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/07/java超大文件上传与下载/ 可以入群一起讨论:374992201
  • 基于socket的多线程文件传输,包中含有整个工程的源代码(有详细的注解) 和 直接运行的打包生成的jar文件 。其中swing界面有待优化.....
  • 使用java socket开发的多线程文件上传下载的实例项目,多线程并发测试中可以支持200个,可能由于我电脑的配置问题,一般在并发大于200时client端可能会出现"阻塞"问题,还请大家指教
  • java socket 多线程网络传输多个文件

    热门讨论 2013-07-14 13:17:18
    java socket 多线程网络传输多个文件
  • Java Socket 多线程网络传输多个文件
  • NULL 博文链接:https://logicluo.iteye.com/blog/2196661
  • 由于需要研究了下用 java socket 传输文件,由于需要传输多个文件,因此,采用了多线程设计。客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的ServerSocket每次 accept 一个 socket...
  • 一有客户端连接就创建两个新的线程来负责这个连接一个负责客62616964757a686964616fe59b9ee7ad9431333262373934户端发送的信息(ClientMsgCollectThread 类),另一个负责通过该Socket发送数据(ServerMsgSendThread )...
  • (文章本人原创,若转载请注明出处)在JDK1.5提供了一个线程池ThreadPoolExecutor,可以处理用户提交过来的线程。如果把要处理的任务比作盖一个大楼,那么每一个建筑工人就相当于一个线程,那么这个ThreadPoolExecutor...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 544
精华内容 217
关键字:

java多线程传输文件

java 订阅