http://www.blogjava.net/sterning/archive/2007/10/13/152508.html

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解。在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度。废话少说,先来看服务器端的程序。

1.服务器端

package sterning;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    int port = 8821;

    void start() {
        Socket s = null;
        try {
            ServerSocket ss = new ServerSocket(port);
            while (true) {
                // 选择进行传输的文件
                String filePath = "D:\\lib.rar";
                File fi = new File(filePath);

                System.out.println("文件长度:" + (int) fi.length());

                // public Socket accept() throws
                // IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。

                s = ss.accept();
                System.out.println("建立socket链接");
                DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));
                dis.readByte();

                DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
                DataOutputStream ps = new DataOutputStream(s.getOutputStream());
                //将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。
                ps.writeUTF(fi.getName());
                ps.flush();
                ps.writeLong((long) fi.length());
                ps.flush();

                int bufferSize = 8192;
                byte[] buf = new byte[bufferSize];

                while (true) {
                    int read = 0;
                    if (fis != null) {
                        read = fis.read(buf);
                    }

                    if (read == -1) {
                        break;
                    }
                    ps.write(buf, 0, read);
                }
                ps.flush();
                // 注意关闭socket链接哦,不然客户端会等待server的数据过来,
                // 直到socket超时,导致数据不完整。                
                fis.close();
                s.close();                
                System.out.println("文件传输完成");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String arg[]) {
        new ServerTest().start();
    }
}

2.socket的Util辅助类

package sterning;

import java.net.*;
import java.io.*;

public class ClientSocket {
    private String ip;

    private int port;

    private Socket socket = null;

    DataOutputStream out = null;

    DataInputStream getMessageStream = null;

    public ClientSocket(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    /**
     * 创建socket连接
     * 
     * @throws Exception
     *             exception
     */
    public void CreateConnection() throws Exception {
        try {
            socket = new Socket(ip, port);
        } catch (Exception e) {
            e.printStackTrace();
            if (socket != null)
                socket.close();
            throw e;
        } finally {
        }
    }

    public void sendMessage(String sendMessage) throws Exception {
        try {
            out = new DataOutputStream(socket.getOutputStream());
            if (sendMessage.equals("Windows")) {
                out.writeByte(0x1);
                out.flush();
                return;
            }
            if (sendMessage.equals("Unix")) {
                out.writeByte(0x2);
                out.flush();
                return;
            }
            if (sendMessage.equals("Linux")) {
                out.writeByte(0x3);
                out.flush();
            } else {
                out.writeUTF(sendMessage);
                out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (out != null)
                out.close();
            throw e;
        } finally {
        }
    }

    public DataInputStream getMessageStream() throws Exception {
        try {
            getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            return getMessageStream;
        } catch (Exception e) {
            e.printStackTrace();
            if (getMessageStream != null)
                getMessageStream.close();
            throw e;
        } finally {
        }
    }

    public void shutDownConnection() {
        try {
            if (out != null)
                out.close();
            if (getMessageStream != null)
                getMessageStream.close();
            if (socket != null)
                socket.close();
        } catch (Exception e) {

        }
    }
}

3.客户端

package sterning;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class ClientTest {
    private ClientSocket cs = null;

    private String ip = "localhost";// 设置成服务器IP

    private int port = 8821;

    private String sendMessage = "Windwos";

    public ClientTest() {
        try {
            if (createConnection()) {
                sendMessage();
                getMessage();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private boolean createConnection() {
        cs = new ClientSocket(ip, port);
        try {
            cs.CreateConnection();
            System.out.print("连接服务器成功!" + "\n");
            return true;
        } catch (Exception e) {
            System.out.print("连接服务器失败!" + "\n");
            return false;
        }

    }

    private void sendMessage() {
        if (cs == null)
            return;
        try {
            cs.sendMessage(sendMessage);
        } catch (Exception e) {
            System.out.print("发送消息失败!" + "\n");
        }
    }

    private void getMessage() {
        if (cs == null)
            return;
        DataInputStream inputStream = null;
        try {
            inputStream = cs.getMessageStream();
        } catch (Exception e) {
            System.out.print("接收消息缓存错误\n");
            return;
        }

        try {
            //本地保存路径,文件名会自动从服务器端继承而来。
            String savePath = "E:\\";
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];
            int passedlen = 0;
            long len=0;
            
            savePath += inputStream.readUTF();
            DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
            len = inputStream.readLong();
            
            System.out.println("文件的长度为:" + len + "\n");
            System.out.println("开始接收文件!" + "\n");
                    
            while (true) {
                int read = 0;
                if (inputStream != null) {
                    read = inputStream.read(buf);
                }
                passedlen += read;
                if (read == -1) {
                    break;
                }
                //下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
                System.out.println("文件接收了" +  (passedlen * 100/ len) + "%\n");
                fileOut.write(buf, 0, read);
            }
            System.out.println("接收完成,文件存为" + savePath + "\n");

            fileOut.close();
        } catch (Exception e) {
            System.out.println("接收消息错误" + "\n");
            return;
        }
    }

    public static void main(String arg[]) {
        new ClientTest();
    }
}

这就实现了从服务器端向客户端发送文件的过程,当然,反过来,也一样.稍有不同.代码中对跨平台的细节没有实现,有时间或兴趣的朋友可以提供一下.

Java基于Socket文件传输示例的更多相关文章

  1. Java基于Socket文件传输示例(转)

    最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加 ...

  2. 基于序列化技术(Protobuf)的socket文件传输

    好像好久都没更博文了,没办法,最近各种倒霉事情,搞到最近真的没什么心情,希望之后能够转运吧. 言归正传,这次我要做的是基于序列化技术的socket文件传输来无聊练一下手. 一.socket文件传输 之 ...

  3. Java简单文件传输 socket简单文件传输示例

    服务器端代码: import java.io.*; import java.net.*; /** * Created with IntelliJ IDEA. * User: HYY * Date: 1 ...

  4. java基于socket的网络通信,实现一个服务端多个客户端的群聊,传输文件功能,界面使用Swing

    最近在复习java的io流及网络编程.但复习写那些样板程序总是乏味的.便准备写个项目来巩固.想来想去还是聊天项目比较好玩.如果日后完成的比较好自己也可以用(哈哈哈).并且自己后面也要继续巩固java多 ...

  5. C++,java信息,文件传输

    java客户端 package client; import java.io.DataOutputStream; import java.io.File; import java.io.FileInp ...

  6. Linux网络编程:socket文件传输范例

    基于TCP流协议的socket网络文件传输Demo: 实现:C语言功能:文件传输(可以传任何格式的文件) /********************************************** ...

  7. Java 简单TCP文件传输

    服务端 package TCP; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputSt ...

  8. Android连接热点的Socket文件传输

    最近把测试丢过来的种种BUG解决后,终于有时间去研究研究Socket通信,再加上以前做的WiFi连接和热点开启,于是有了现在的这篇博文:创建热点发送文件,让另一台手机连接热点接收文件. 效果图: 两台 ...

  9. java基于socket公共聊天室的实现

    项目:一个公共聊天室功能的实现,实现了登录聊天,保存聊天记录等功能. 一.实现代码 1.客户端 ChatClient.java import java.io.BufferedReader; impor ...

随机推荐

  1. Hunters

    Hunters Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submi ...

  2. 兼容IE低版本

    1,IE6PNG透明的bug,只需要把png图另存为无杂边的png-8格式 2,在IE6用overflow:hidden清除浮动,要加上zoom:1 3,IE6下盒子的最小高度为20px 如果要小于2 ...

  3. centos6.5安装docker

    (一) 查看系统的版本和内核: $cat /etc/issue $uname -r 因为docker要求服务CentOS6以上,kernel 版本必须2.6.32-431或更高 要将Docker安装到 ...

  4. http get with body data

    http://stackoverflow.com/questions/978061/http-get-with-request-body Yes, you can send a request bod ...

  5. 转 由一次磁盘告警引发的血案:du 和 ls 的区别

    如果你完全不明白或者完全明白图片含义, 那么你不用继续往下看了. 否则, 这篇文章也许正是你需要的. 背景 确切地说,不是收到的自动告警短信或者邮件告诉我某机器上的磁盘满了,而是某同学人肉发现该机器写 ...

  6. Java中的一些术语的解释

    一  API(Application Programming Interface,应用程序编程接口) 简单来说,就是其他人开发出来一块程序,你想用,他会告诉你调用哪个函数,给这个函数传什么参数,然后又 ...

  7. 【prim + kruscal 】 最小生成树模板

    来源:dlut oj 1105: Zhuo’s Dream Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 40 Solved: 14[Submit][St ...

  8. PHP 上传图片,生成水印,支持文字, gif, png

    //admin_upfile.php <html> <meta http-equiv="Content-Type" content="text/html ...

  9. Linux标准目录

    本文参考鸟哥的linux私房菜 /bin 获得最小的系统可操作性所需要的命令 /boot 内核和加载内核所需要的文件 /dev 终端.磁盘.调制解调器等的设备项 /etc 关键的启动文件和配置文件 / ...

  10. JAVA-面向对象2--继承

    1. 继承的好处: 1.提高代码复用性. 2.让类与类之间产生关系,为面向对象的第三大特征 多态 提供了前提 2.java中支持单继承,不直接支持多继承,但对c++中多继承进行了改良.java通过多实 ...