Socket实现文件传输,序列化与反序列化的认识


socket通信,完成文件传输

      本文是一个基于TCP,一对多的文件传输小案例代码如下:

服务端:

/**
 * 服务端
 * */
public class server extends ServerSocket {
    /**
     * 构造函数
     * */
    public server()throws IOException{
        super(8999);
    }
    /**
     * 连接
     * */
    public void load()throws Exception{
        System.out.println("等待连接------------");
       while(true){
           Socket socket = this.accept();
           System.out.println("IP:"+socket.getInetAddress()+"已连接");
           new Thread(new mutiClient(socket),"客户端1").start();
           System.out.println(Thread.currentThread().getName());
       }

    }
    public static void main(String[] args){
        try{
            server s = new server();
            s.load();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
  /**
   * 线程类
   * */
  class mutiClient implements Runnable{
      private  Socket socket;
      private  ObjectInputStream  ois;
      private  FileOutputStream oos;
      public mutiClient(Socket socket){
          this.socket = socket;
      }
      @Override
      public void run(){
          try {
              ois = new ObjectInputStream(socket.getInputStream());
              String fileName = ois.readUTF();
              long fileLength = ois.readLong();
              File directory = new File("E:\\socket");
              if (!directory.exists()) {
                  directory.mkdir();
              }
              File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);
               oos = new FileOutputStream(file);
              System.out.println("-------开始接收文件-------");
              byte[] bytes = new byte[1024];
              int length = 0;
              while((length = ois.read(bytes, 0, bytes.length)) != -1) {
                  oos.write(bytes, 0, length);
                  oos.flush();
              }
              System.out.println("-------文件接收成功 -------");
          } catch (Exception e) {
              e.printStackTrace();
          }finally {
              try {
                  ois.close();
                  oos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  }

客户端 

/**
 * 客户端
 * */
public class client extends Socket{
    private Socket client;
    /**
     * 构造方法
     * @throws IOException
     * */
    public client() throws IOException {
        super("127.0.0.1",8999);
        this.client = this;
        System.out.println("**->"+client.getInetAddress()+"已成功连接服务器");
    }
    /**
     * 发送文件
     * @param file
     * @throws Exception
     * */
    public void  sendFile(File file)throws Exception{
        FileInputStream  ois = new FileInputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        oos.writeUTF(file.getName());
        oos.flush();
        oos.writeLong(file.length());
        oos.flush();

        // 开始传输文件
        System.out.println("开始传送-----------------");
        byte[] bytes = new byte[1024];
        int length = 0;
        long pro = 0;
        while ((length = ois.read(bytes, 0, bytes.length)) != -1) {
            oos.write(bytes, 0, length);
            oos.flush();
            pro += length;
        }
        System.out.println();
        System.out.println("传送结束----------------");
        ois.close();
        oos.close();
    }

    public static void main(String[] args){
        try{
            client c = new client();
            c.sendFile(new File("E:\\User.bat"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

可以同时开启多个客户端进行文件发送,一个服务端进行接收。

 

知识点:

    TCP的socket通信有三次握手的一个过程:

Socket   socket  =   server.accept();

    服务端的accept()方法一直在端口侦听连接到的套接字,并接受它。该方法将阻塞直

到建立连接。

在进行初步连接的时候,客户端要知道服务端的Ip地址和端口号即套接字。而服务端要指定端口号

 二.序列化和反序列化


将对象序列化存储在磁盘上,再反序列化读取的一个过程。
1.首先定义一个类User,该类的对象要实现序列化,就要实现Serializable接口。
2.下来就可以进行序列化操作:

 ObjectOutputStream   oos = new ObjectOutputStream(new FileOutputStream(new File("E:\\User.bat")));
User user1 = new User("1410064201","杜涛",22,"陕西榆林");
oos.writeObject(user1);

ObjectOutputStream中的writeObject()方法可以写入对象,原始数据类型可以使用DataOutputStream写入,也可以使用该方法写入

3. 反序列化操作:

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:\\User.bat")));

User user1 = (User)ois.readObject();

 readObject()方法在反序列化的时候,必须保持和序列化每一步相同的类型,即读取的顺序不能变,在反序列化的过程中,我们需要强转类型,因为在之前,我们把数据都封装在某个文件中,往出拿的时候才知道是什么类型。

猜你喜欢

转载自blog.csdn.net/xiaojinsanMM/article/details/81207220